commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pste...@apache.org
Subject svn commit: r1055270 - in /commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool: Waiter.java WaiterFactory.java
Date Wed, 05 Jan 2011 01:55:38 GMT
Author: psteitz
Date: Wed Jan  5 01:55:37 2011
New Revision: 1055270

URL: http://svn.apache.org/viewvc?rev=1055270&view=rev
Log:
Added test factory and object class.

Added:
    commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java   (with
props)
    commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java
  (with props)

Added: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java?rev=1055270&view=auto
==============================================================================
--- commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java (added)
+++ commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java Wed
Jan  5 01:55:37 2011
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.pool;
+
+/**
+ * <p>Object created by {@link WaiterFactory}. Maintains active / valid state,
+ * last passivated and idle times.  Waits with configurable latency when 
+ * {@link #doWait()} method is called.</p>
+ *
+ * <p>This class is *not* threadsafe.</p>
+ */
+public class Waiter {
+    private boolean active = false;
+    private boolean valid = true;
+    private long latency = 0;
+    private long lastPassivated = 0;
+    private long lastIdleTimeMs = 0;
+    
+    public Waiter(boolean active, boolean valid, long latency) {
+        this.active = active;
+        this.valid = valid;
+        this.latency = latency;
+        this.lastPassivated = System.currentTimeMillis();
+    }
+
+    /**
+     * Wait for {@link #getLatency()} ms.
+     */
+    public void doWait() {
+        try {
+            Thread.sleep(latency);
+        } catch (InterruptedException ex) {
+            // ignore
+        }
+    }
+
+    /**
+     * Whether or not the instance is active.
+     * 
+     * @return true if the last lifecycle event for this instance was activation.
+     */
+    public boolean isActive() {
+        return active;
+    }
+
+    /**
+     * <p>Sets the active state and updates {@link #getLastIdleTimeMs() lastIdleTime}
+     * or {@link #getLastPassivated() lastPassivated} as appropriate.</p>
+     * 
+     * <p>If the active state is changing from inactive to active, lastIdleTime
+     * is updated with the current time minus lastPassivated.  If the state is
+     * changing from active to inactive, lastPassivated is updated with the
+     * current time.</p>
+     * 
+     * <p>{@link WaiterFactory#activateObject(Object)} and
+     * {@link WaiterFactory#passivateObject(Object)} invoke this method on their
+     * actual parameter, passing <code>true</code> and <code>false</code>,
+     * respectively.</p>
+     * 
+     * @param active new active state
+     */
+    public void setActive(boolean active) {
+        final boolean activeState = this.active;
+        if (activeState == active) {
+            return;
+        }
+        this.active = active;
+        final long currentTime = System.currentTimeMillis();
+        if (active) {  // activating
+            lastIdleTimeMs = currentTime - lastPassivated;
+        } else {       // passivating
+            lastPassivated = currentTime;
+        }
+    }
+
+    public long getLatency() {
+        return latency;
+    }
+
+    public void setLatency(long latency) {
+        this.latency = latency;
+    }
+
+    public boolean isValid() {
+        return valid;
+    }
+
+    public void setValid(boolean valid) {
+        this.valid = valid;
+    }
+    
+    /**
+     * <p>Returns the system time of this instance's last passivation.</p>
+     * 
+     * <p>When an instance is created, this field is initialized to the system time.</p>
+     * 
+     * @return time of last passivation
+     */
+    public long getLastPassivated() {
+        return lastPassivated;
+    }
+    
+    /**
+     * <p>Returns the last idle time for this instance in ms.</p>
+     * 
+     * <p>When an instance is created, and each subsequent time it is passivated,
+     * the {@link #getLastPassivated() lastPassivated} property is updated with the
+     * current time.  When the next activation occurs, <code>lastIdleTime</code>
is
+     * updated with the elapsed time since passivation.<p>
+     * 
+     * @return last idle time
+     */
+    public long getLastIdleTimeMs() {
+        return lastIdleTimeMs;
+    }
+    
+}

Propchange: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/Waiter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java?rev=1055270&view=auto
==============================================================================
--- commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java
(added)
+++ commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java
Wed Jan  5 01:55:37 2011
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.pool;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Iterator;
+
+import org.apache.commons.pool.PoolableObjectFactory;
+import org.apache.commons.pool.KeyedPoolableObjectFactory;
+
+/**
+ * Object factory with configurable latencies for object lifecycle methods.
+ * This factory will also track and enforce maxActive, maxActivePerKey contracts.
+ * If the factory's maxActive / maxActivePerKey are set to match those of the
+ * pool, makeObject will throw IllegalStateException if the number of makes - destroys
+ * (per key) exceeds the configured max.
+ *
+ */
+public class WaiterFactory implements PoolableObjectFactory,
+KeyedPoolableObjectFactory {
+    
+    /** Latency of activateObject */
+    private final long activateLatency;
+    
+    /** Latency of destroyObject */
+    private final long destroyLatency;
+    
+    /** Latency of makeObject */
+    private final long makeLatency;
+    
+    /** Latency of passivateObject */
+    private final long passivateLatency;
+    
+    /** Latency of validateObject */
+    private final long validateLatency;
+    
+    /** Latency of doWait for Waiter instances created by this factory */
+    private final long waiterLatency;
+    
+    /** Probability that passivation will invalidate Waiter instances */
+    private final double passivateInvalidationProbability;
+    
+    /** Count of (makes - destroys) since last reset */
+    private long activeCount = 0;
+    
+    /** Count of (makes - destroys) per key since last reset */
+    private Map activeCounts = new HashMap();
+    
+    /** Maximum of (makes - destroys) - if exceeded IllegalStateException */
+    private final long maxActive;  // GKOP 1.x calls this maxTotal
+    
+    /** Maximum of (makes - destroys) per key */
+    private final long maxActivePerKey;  // GKOP 1.x calls this maxActive
+
+    public WaiterFactory(long activateLatency, long destroyLatency,
+            long makeLatency, long passivateLatency, long validateLatency,
+            long waiterLatency,long maxActive, long maxActivePerKey,
+            double passivateInvalidationProbability) {
+        this.activateLatency = activateLatency;
+        this.destroyLatency = destroyLatency;
+        this.makeLatency = makeLatency;
+        this.passivateLatency = passivateLatency;
+        this.validateLatency = validateLatency;
+        this.waiterLatency = waiterLatency;
+        this.maxActive = maxActive;
+        this.maxActivePerKey = maxActivePerKey;
+        this.passivateInvalidationProbability = passivateInvalidationProbability;
+    }
+    
+    public WaiterFactory(long activateLatency, long destroyLatency,
+            long makeLatency, long passivateLatency, long validateLatency,
+            long waiterLatency) {
+        this(activateLatency, destroyLatency, makeLatency, passivateLatency,
+                validateLatency, waiterLatency, Long.MAX_VALUE, Long.MAX_VALUE, 0);
+    }
+    
+    public WaiterFactory(long activateLatency, long destroyLatency,
+            long makeLatency, long passivateLatency, long validateLatency,
+            long waiterLatency,long maxActive) {
+        this(activateLatency, destroyLatency, makeLatency, passivateLatency,
+                validateLatency, waiterLatency, maxActive, Long.MAX_VALUE, 0);
+    }
+
+    public void activateObject(Object obj) throws Exception {
+        doWait(activateLatency);
+        ((Waiter) obj).setActive(true);
+    }
+
+    public void destroyObject(Object obj) throws Exception {
+        doWait(destroyLatency);
+        ((Waiter) obj).setValid(false);
+        ((Waiter) obj).setActive(false);
+        // Decrement *after* destroy 
+        synchronized (this) {
+            activeCount--;
+        }
+    }
+
+    public Object makeObject() throws Exception {
+        // Increment and test *before* make
+        synchronized (this) {
+            if (activeCount >= maxActive) {
+                throw new IllegalStateException("Too many active instances: " +
+                activeCount + " in circulation with maxActive = " + maxActive);
+            } else {
+                activeCount++;
+            }
+        }
+        doWait(makeLatency);
+        return new Waiter(false, true, waiterLatency);
+    }
+
+    public void passivateObject(Object arg0) throws Exception {
+        ((Waiter) arg0).setActive(false);
+        doWait(passivateLatency);
+        if (Math.random() < passivateInvalidationProbability) {
+            ((Waiter) arg0).setValid(false);
+        }
+    }
+
+    public boolean validateObject(Object arg0) {
+        doWait(validateLatency);
+        return ((Waiter) arg0).isValid();
+    }
+    
+    protected void doWait(long latency) {
+        try {
+            Thread.sleep(latency);
+        } catch (InterruptedException ex) {
+            // ignore
+        }
+    }
+    
+    public synchronized void reset() {
+        activeCount = 0;
+        if (activeCounts.isEmpty()) {
+            return;
+        }
+        Iterator it = activeCounts.keySet().iterator();
+        while (it.hasNext()) {
+            Object key = it.next();
+            activeCounts.put(key, new Integer (0));
+        }
+    }
+
+    /**
+     * @return the maxActive
+     */
+    public synchronized long getMaxActive() {
+        return maxActive;
+    }
+
+    // KeyedPoolableObjectFactory methods
+    
+    public void activateObject(Object key, Object obj) throws Exception {
+        activateObject(obj);
+    }
+
+    public void destroyObject(Object key, Object obj) throws Exception {
+        destroyObject(obj);
+        synchronized (this) {
+            Integer count = (Integer) activeCounts.get(key);
+            activeCounts.put(key, new Integer(count.intValue() - 1));
+        }
+    }
+
+    public Object makeObject(Object key) throws Exception {
+        synchronized (this) {
+            Integer count = (Integer) activeCounts.get(key);
+            if (count == null) {
+                count = new Integer(1);
+                activeCounts.put(key, count);
+            } else {
+                if (count.intValue() >= maxActivePerKey) {
+                    throw new IllegalStateException("Too many active " +
+                    "instances for key = " + key + ": " + count.intValue() + 
+                    " in circulation " + "with maxActivePerKey = " + 
+                    maxActivePerKey);
+                } else {
+                    activeCounts.put(key, new Integer(count.intValue() + 1));
+                }
+            }
+        }
+        return makeObject();
+    }
+
+    public void passivateObject(Object key, Object obj) throws Exception {
+        passivateObject(obj);
+    }
+
+    public boolean validateObject(Object key, Object obj) {
+        return validateObject(obj);
+    }
+
+}

Propchange: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/WaiterFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message