/// <summary> /// Destroy the wrapped, pooled object. /// </summary> /// <param name="key"></param> /// <param name="toDestroy"></param> /// <param name="always"></param> private bool Destroy(K key, IPooledObject <T> toDestroy, bool always) { ObjectDeque <T> objectDeque = Register(key); try { bool isIdle = objectDeque.GetIdleObjects().Remove(toDestroy); if (isIdle || always) { objectDeque.GetAllObjects().TryRemove(new IdentityWrapper <T>(toDestroy.GetObject()), out toDestroy); toDestroy.Invalidate(); try { factory.DestroyObject(key, toDestroy); } finally { createdCount--; destroyedCount++; numTotal--; } return(true); } else { return(false); } } finally { Deregister(key); } }
private void Destroy(IPooledObject <T> toDestroy) { IPooledObject <T> obj; toDestroy.Invalidate(); idleObjects.Remove(toDestroy); _allObjects.TryRemove(new IdentityWrapper <T>(toDestroy.GetObject()), out obj); try { factory.DestroyObject(toDestroy); } finally { createCount++; } }
/// <summary> /// Recover abandoned objects which have been checked out but /// not used since longer than the removeAbandonedTimeout. /// </summary> /// <param name="ac"></param> private void RemoveAbandoned(AbandonedConfig ac) { long now = DateTime.Now.CurrentTimeMillis(); long timeout = now - ac.getRemoveAbandonedTimeout() * 1000L; List <IPooledObject <T> > remove = new List <IPooledObject <T> >(); IEnumerator <IPooledObject <T> > it = _allObjects.Values.GetEnumerator(); do { IPooledObject <T> pooledObject = it.Current; lock (pooledObject) { if (pooledObject.GetState() == PooledObjectState.Allocated && pooledObject.GetLastUsedTime() <= timeout) { pooledObject.MarkAbandoned(); remove.Add(pooledObject); } } } while (it.MoveNext()); // Now remove the abandoned objects IEnumerator <IPooledObject <T> > itr = remove.GetEnumerator(); do { IPooledObject <T> pooledObject = itr.Current; try { InvalidateObject(pooledObject.GetObject()); } catch (Exception ex) { throw ex; } } while (itr.MoveNext()); }
public T BorrowObject(long borrowMaxWaitMillis) { AssertOpen(); AbandonedConfig ac = this.abandonedConfig; if (ac != null && ac.getRemoveAbandonedOnBorrow() && (GetNumIdle() < 2) && (GetNumActive() > GetMaxTotal() - 3)) { RemoveAbandoned(ac); } IPooledObject <T> p = null; // Get local copy of current config so it is consistent for entire // method execution bool blockWhenExhausted = getBlockWhenExhausted(); bool create; long waitTime = DateTime.Now.CurrentTimeMillis(); while (p == null) { create = false; if (blockWhenExhausted) { p = idleObjects.RemoveFront(); if (p == null) { p = Create(); if (p != null) { create = true; } } if (p == null) { if (borrowMaxWaitMillis < 0) { p = idleObjects.First(); } else { p = idleObjects.RemoveFront(); } } if (p == null) { throw new Exception( "Timeout waiting for idle object"); } if (!p.Allocate()) { p = null; } } else { p = idleObjects.RemoveFront(); if (p == null) { p = Create(); if (p != null) { create = true; } } if (p == null) { throw new Exception("Pool exhausted"); } if (!p.Allocate()) { p = null; } } if (p != null) { try { factory.ActivateObject(p); } catch (Exception e) { try { Destroy(p); } catch (Exception e1) { // Ignore - activation failure is more important } p = null; if (create) { throw new Exception("Unable to activate object"); } } if (p != null && (GetTestOnBorrow() || create && getTestOnCreate())) { bool validate = false; // Throwable validationThrowable = null; try { validate = factory.ValidateObject(p); } catch (Exception t) { throw t; // validationThrowable = t; } if (!validate) { try { Destroy(p); } catch (Exception e) { // Ignore - validation failure is more important } p = null; if (create) { throw new Exception("Unable to activate object"); } } } } } UpdateStatsBorrow(p, DateTime.Now.CurrentTimeMillis() - waitTime); return(p.GetObject()); }
private T BorrowObject(K key, long borrowMaxWaitMillis) { AssertOpen(); IPooledObject <T> p = null; // Get local copy of current config so it is consistent for entire // method execution bool blockWhenExhausted = getBlockWhenExhausted(); bool create; long waitTime = DateTime.Now.CurrentTimeMillis(); ObjectDeque <T> objectDeque = Register(key); try { while (p == null) { create = false; if (blockWhenExhausted) { p = objectDeque.GetIdleObjects().RemoveFront(); if (p == null) { p = Create(key); if (p != null) { create = true; } } if (p == null) { if (borrowMaxWaitMillis < 0) { p = objectDeque.GetIdleObjects().TakeFront(); } else { p = objectDeque.GetIdleObjects().RemoveFront(); } } if (p == null) { throw new Exception( "Timeout waiting for idle object"); } if (!p.Allocate()) { p = null; } } else { p = objectDeque.GetIdleObjects().RemoveFront(); if (p == null) { p = Create(key); if (p != null) { create = true; } } if (p == null) { throw new Exception("Pool exhausted"); } if (!p.Allocate()) { p = null; } } if (p != null) { try { factory.ActivateObject(key, p); } catch (Exception e) { try { Destroy(key, p, true); } catch (Exception) { // ignore } p = null; if (create) { throw new Exception("Unable to activate object"); } } if (p != null && (GetTestOnBorrow() || create && getTestOnCreate())) { bool validate = false; try { validate = factory.ValidateObject(key, p); } catch (Exception) { throw; } if (!validate) { try { Destroy(key, p, true); destroyedByBorrowValidationCount++; } catch (Exception) { // Ignore - validation failure is more important } p = null; if (create) { throw new Exception("Unable to validate object"); } } } } } } finally { Deregister(key); } UpdateStatsBorrow(p, DateTime.Now.CurrentTimeMillis() - waitTime); return(p.GetObject()); }
private IPooledObject <T> Create(K key) { int maxTotalPerKeySave = GetMaxTotalPerKey(); // Per key int maxTotal = GetMaxTotal(); // All keys // Check against the overall limit bool loop = true; while (loop) { int newNumTotal = ++numTotal; if (maxTotal > -1 && newNumTotal > maxTotal) { --numTotal; if (GetNumIdle() == 0) { return(null); } else { ClearOldest(); } } else { loop = false; } } ObjectDeque <T> objectDeque; poolMap.TryGetValue(key, out objectDeque); long newCreateCount = objectDeque.GetCreateCount() + 1; // Check against the per key limit if (maxTotalPerKeySave > -1 && newCreateCount > maxTotalPerKeySave || newCreateCount > 0x7fffffff) { --numTotal; objectDeque.DecrementAndGet(); return(null); } IPooledObject <T> p = null; try { p = factory.MakeObject(key); } catch (Exception e) { numTotal--; objectDeque.DecrementAndGet(); throw e; } ++createdCount; objectDeque.GetAllObjects().TryAdd(new IdentityWrapper <T>(p.GetObject()), p); return(p); }