/** * Attempt to aquire a permit to add the object to the pool. * * @param obj object to add to the pool * @return true of the item as added */ public boolean add(T obj) { return add(obj, 0); }
/** * This internal method allows us to "swap" the status * of two entries before returning them to the pool. * <p/> * This allows us to elect a replacement in the min pool * without ever loosing loosing pool consistency. * <p/> * Neither argument is allowed to be null. * * @param hard the "min" pool item that will be discarded * @param soft the "min" pool item to replace the discarded instance */ private void discardAndReplace(final Entry hard, final Entry soft) { // The replacement becomes a hard reference -- a "min" pool item soft.hard.set(soft.active()); push(soft); // The discarded item becomes a soft reference hard.hard.set(null); discard(hard); }
public void flush() { this.pool.flush(); }
/** * Never call this method without having successfully called * {@link #pop(long, TimeUnit)} beforehand. * <p/> * Failure to do so will increase the max pool size by one. * * @param obj object to push onto the pool * @return false if the pool max size was exceeded */ public boolean push(final T obj) { return push(obj, 0); }
public Pool(int max, int min, boolean strict, long maxAge, long idleTimeout, long interval, Executor executor, Supplier<T> supplier, boolean replaceAged, double maxAgeOffset) { if (min > max) greater("max", max, "min", min); if (maxAge != 0 && idleTimeout > maxAge) greater("MaxAge", maxAge, "IdleTimeout", idleTimeout); this.executor = executor != null ? executor : createExecutor(); this.supplier = supplier != null ? supplier : new NoSupplier(); this.available = (strict) ? new Semaphore(max) : new Overdraft(); this.minimum = new Semaphore(min); this.instances = new Semaphore(max); this.maxAge = maxAge; this.maxAgeOffset = maxAgeOffset; this.replaceAged = replaceAged; if (interval == 0) interval = 5 * 60 * 1000; // five minutes this.interval = interval; this.sweeper = new Sweeper(idleTimeout, max); this.stats = new Stats(min, max, idleTimeout); }
public boolean close(final long timeout, final TimeUnit unit) throws InterruptedException { // Stop the sweeper thread stop(); // drain all keys so no new instances will be accepted into the pool while (instances.tryAcquire()) { Thread.yield(); } while (minimum.tryAcquire()) { Thread.yield(); } // flush and sweep flush(); try { sweeper.run(); } catch (final Exception ignore) { //no-op } // Drain all leases if (!(available instanceof Overdraft)) { while (available.tryAcquire()) { Thread.yield(); } available.drainPermits(); } instances.drainPermits(); minimum.drainPermits(); // Wait for any pending discards return out.await(timeout, unit); }
/** * Used when a call to pop() was made that returned null * indicating that the caller has a permit to create an * object for this pool, but the caller will not be exercising * that permit and wishes intstead to return "null" to the pool. */ public void discard() { discard(null); }
/** * Any successful pop() call requires a corresponding push() or discard() call * <p/> * A pop() call that returns null is considered successful. * * @param timeout time to block while waiting for an instance * @param unit unit of time dicated by the timeout * @return an entry from the pool or null indicating permission to create and push() an instance into the pool * @throws InterruptedException vm level thread interruption * @throws IllegalStateException if a permit could not be acquired * @throws TimeoutException if no instance could be obtained within the timeout */ public Entry pop(final long timeout, final TimeUnit unit) throws InterruptedException, TimeoutException { return pop(timeout, unit, true); }
public void deploy(CoreDeploymentInfo deploymentInfo) { Options options = new Options(deploymentInfo.getProperties()); final Pool.Builder builder = new Pool.Builder(poolBuilder); String timeString = options.get("Timeout", this.timeout.toString()); timeString = options.get("AccessTimeout", timeString); Duration accessTimeout = new Duration(timeString); final ObjectRecipe recipe = PassthroughFactory.recipe(builder); recipe.setAllProperties(deploymentInfo.getProperties()); builder.setSupplier(new StatelessSupplier(deploymentInfo)); builder.setExecutor(executor); Data data = new Data(builder.build(), accessTimeout); deploymentInfo.setContainerData(data); final int min = builder.getMin(); long maxAge = builder.getMaxAge().getTime(TimeUnit.MILLISECONDS); double maxAgeOffset = builder.getMaxAgeOffset(); for (int i = 0; i < min; i++) { Instance obj = createInstance(deploymentInfo); if (obj == null) continue; long offset = maxAge > 0 ? ((long) (maxAge / min * i * maxAgeOffset)) % maxAge : 0l; data.getPool().add(obj, offset); } data.getPool().start(); }
@SuppressWarnings("unchecked") public Pool<T> build() { //noinspection unchecked final Pool pool = new Pool(max, min, strict, maxAge.getTime(MILLISECONDS), idleTimeout.getTime(MILLISECONDS), interval.getTime(MILLISECONDS), executor, supplier, replaceAged, maxAgeOffset, this.garbageCollection, replaceFlushed); if (scheduledExecutorService != null) { pool.scheduler.set(scheduledExecutorService); } return pool; } }
data.getPool().start();
public void undeploy(CoreDeploymentInfo deploymentInfo) { Data data = (Data) deploymentInfo.getContainerData(); if (data == null) return; data.getPool().stop(); //TODO *maybe* call ejbRemove on each bean in pool. deploymentInfo.setContainerData(null); }
/** * Never call this method without having successfully called * {@link #pop(long, java.util.concurrent.TimeUnit)} beforehand. * <p/> * Failure to do so will increase the max pool size by one. * * @param obj object to push onto the pool * @return false if the pool max size was exceeded */ public boolean push(T obj) { return push(obj, 0); }
@SuppressWarnings("unchecked") public Pool(final int max, final int min, final boolean strict, final long maxAge, final long idleTimeout, long sweepInterval, final Executor executor, final Supplier<T> supplier, final boolean replaceAged, final double maxAgeOffset, final boolean garbageCollection, final boolean replaceFlushed) { if (min > max) { greater("max", max, "min", min); } if (maxAge != 0 && idleTimeout > maxAge) { greater("MaxAge", maxAge, "IdleTimeout", idleTimeout); } this.executor = executor != null ? executor : createExecutor(); this.supplier = supplier != null ? supplier : new NoSupplier(); this.available = strict ? new Semaphore(max) : new Overdraft(max); this.minimum = new Semaphore(min); this.instances = new Semaphore(max); this.maxAge = maxAge; this.maxAgeOffset = maxAgeOffset; this.replaceAged = replaceAged; this.replaceFlushed = replaceFlushed; if (sweepInterval == 0) { sweepInterval = 5 * 60 * 1000; // five minutes } this.sweepInterval = sweepInterval; this.sweeper = new Sweeper(idleTimeout, max); this.stats = new Stats(min, max, idleTimeout); this.garbageCollection = garbageCollection; }
public boolean close(final long timeout, final TimeUnit unit) throws InterruptedException { // Stop the sweeper thread stop(); // drain all keys so no new instances will be accepted into the pool while (instances.tryAcquire()) { Thread.yield(); } while (minimum.tryAcquire()) { Thread.yield(); } // flush and sweep flush(); try { sweeper.run(); } catch (final Exception ignore) { //no-op } // Drain all leases if (!(available instanceof Overdraft)) { while (available.tryAcquire()) { Thread.yield(); } available.drainPermits(); } instances.drainPermits(); minimum.drainPermits(); // Wait for any pending discards return out.await(timeout, unit); }
/** * Used when a call to pop() was made that returned null * indicating that the caller has a permit to create an * object for this pool, but the caller will not be exercising * that permit and wishes intstead to return "null" to the pool. */ public void discard() { discard(null); }
/** * Any successful pop() call requires a corresponding push() or discard() call * <p/> * A pop() call that returns null is considered successful. * * @param timeout time to block while waiting for an instance * @param unit unit of time dicated by the timeout * @return an entry from the pool or null indicating permission to create and push() an instance into the pool * @throws InterruptedException vm level thread interruption * @throws IllegalStateException if a permit could not be acquired * @throws TimeoutException if no instance could be obtained within the timeout */ public Entry pop(final long timeout, final TimeUnit unit) throws InterruptedException, TimeoutException { return pop(timeout, unit, true); }
public Pool<T> build() { //noinspection unchecked return new Pool(max, min, strict, maxAge.getTime(MILLISECONDS), idleTimeout.getTime(MILLISECONDS), interval.getTime(MILLISECONDS), executor, supplier, replaceAged, maxAgeOffset, this.garbageCollection, replaceFlushed); } }
data.getPool().start();