/// <summary> /// Adds a pool to the factory. /// </summary> /// <typeparam name="TPooled">The pooled item</typeparam> /// <param name="pool">The pool.</param> /// <param name="configuration">The configuration.</param> private void AddPool <TPooled>(PoolBaseOfT <TPooled> pool, PoolConfiguration configuration) where TPooled : class { PoolLookup <TPooled> .Init(pool); this.pools.Add(pool); pool.Initialize(configuration); }
/// <summary> /// Reconfigures the logging timer. /// Will either start a timer or stop it depending on the settings. /// </summary> /// <param name="configuration">the configuration.</param> private void ReconfigureTimer(PoolConfiguration configuration) { if (configuration.OutputPoolStatisticsInLogFiles && this.statsTimer == null && configuration.Enabled) { this.StartStatsTimer(configuration); return; } if (!configuration.OutputPoolStatisticsInLogFiles && this.statsTimer != null) { this.ShutdownStatsTimer(); } }
/// <summary> /// Starts the logging timer. /// </summary> /// <param name="configuration">the configuration.</param> private void StartStatsTimer(PoolConfiguration configuration) { if (this.statsTimer != null) { this.ShutdownStatsTimer(); } this.statsTimer = new Timer( this.ReportStats, configuration, configuration.OutputPoolStatisticsInterval * 1000, Timeout.Infinite); }
/// <summary> /// ReInitializes the pool factory and all pools in it, with the given configuration. /// </summary> /// <param name="configuration">The configuration.</param> public void ReInitialize(PoolConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException("configuration"); } this.ReconfigureTimer(configuration); foreach (var pool in this.pools) { try { pool.ReInitialize(configuration); } catch (Exception e) { InternalLogger.Error("Failed to re-initialize pool:{0} because of exception:{1}", pool.Name, e); } } }
// TODO: Add more pools, there are still stuff that gets allocated. /// <summary> /// Initializes the pool factory with the given pool configuration. /// Will instantiate the pools, but not start them unless configuration says so. /// </summary> /// <param name="configuration">the configuration.</param> public PoolFactory(PoolConfiguration configuration) { int arraySize = 90000; var charArrayPool = new CharArrayPool((int)(10 * arraySize * PoolFactor), (int)(arraySize * PoolFactor), configuration.PrefillPools); var asyncLogEventInfoListPool = new AsyncLogEventInfoListPool(5, (int)(10 * PoolFactor), configuration.PrefillPools); this.AddPool(charArrayPool, configuration); this.AddPool(asyncLogEventInfoListPool, configuration); this.AddPool(new ByteArrayPool((int)(10 * arraySize * PoolFactor), (int)(arraySize * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new StringBuilderPool((int)(10 * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new SingleCallContinuationPool((int)(10 * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new LogEventInfoPool((int)(10 * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new FileNameDictionaryPool(asyncLogEventInfoListPool, 10, 5, configuration.PrefillPools), configuration); this.AddPool(new AsyncContinuationListPool(10, configuration.PrefillPools), configuration); this.AddPool(new CombinedAsyncContinuationPool((int)(10 * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new GenericPool <Counter>((int)(10 * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new GenericPool <ContinueWhenAll>((int)(10 * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new ExceptionHandlerPool((int)(10 * PoolFactor), configuration.PrefillPools), configuration); this.AddPool(new AsyncLogEventInfoArrayPool((int)(10 * arraySize * PoolFactor), (int)(arraySize * PoolFactor)), configuration); this.AddPool(new MemoryStreamPool((int)(10 * PoolFactor)), configuration); }
/// <summary> /// Timer callback method that will log the stats. /// </summary> /// <param name="o">mandatory object parameter. (Not used)</param> private void ReportStats(object o) { StringBuilder builder = null; try { PoolConfiguration configuration = (PoolConfiguration)o; builder = this.Get <StringBuilderPool, StringBuilder>().Get(); builder.Append(StatsPoolNameChars, 0, StatsPoolNameChars.Length); builder.Append('|'); builder.Append(StatsPoolSizeChars, 0, StatsPoolSizeChars.Length); builder.Append('|'); builder.Append(StatsObjectsInPoolChars, 0, StatsObjectsInPoolChars.Length); builder.Append('|'); builder.Append(StatsInUseChars, 0, StatsInUseChars.Length); builder.Append('|'); builder.Append(StatsGivenOutChars, 0, StatsGivenOutChars.Length); builder.Append('|'); builder.Append(StatsThrownAwayChars, 0, StatsThrownAwayChars.Length); builder.Append('|'); builder.Append(StatsNewLine, 0, StatsNewLine.Length); foreach (var pool in this.pools) { pool.WriteStatsTo(builder); } if (configuration.ResetPoolStatisticsAfterReporting) { lock (this.pools) { foreach (var pool in this.pools) { pool.ResetStats(); } } } if (!string.IsNullOrEmpty(configuration.PoolStatisticsLoggerName)) { LogManager.GetLogger(configuration.PoolStatisticsLoggerName).Info(builder.ToString()); } else { InternalLogger.Info(builder.ToString()); } this.statsTimer.Change(configuration.OutputPoolStatisticsInterval * 1000, Timeout.Infinite); } catch (Exception e) { InternalLogger.Error("Error occured while reporting pool statistics:{0}", e); } finally { if (builder != null) { try { this.PutBack(builder); } catch (Exception e) { InternalLogger.Error("Error occured while putting back string builder slim into the pool:{0}", e); } } } }