public async Task MaintenanceTaskCompletesWhenPoolIsGarbageCollected() { var client = new SessionTestingSpannerClient(); var options = new SessionPoolOptions { MinimumPooledSessions = 10, MaintenanceLoopDelay = TimeSpan.FromMinutes(1) }; var sessionPool = new SessionPool(client, options, client.Logger); var waitingTask = sessionPool.WaitForPoolAsync(s_sampleDatabaseName); await client.Scheduler.RunAsync(TimeSpan.FromMinutes(5.5)); await waitingTask; var maintenanceCount = client.Logger.GetEntries(LogLevel.Debug).Count(entry => entry.Contains("maintenance")); Assert.InRange(maintenanceCount, 5, 6); // Make sure the session pool is "alive" up until this point GC.KeepAlive(sessionPool); var weakReference = new WeakReference <SessionPool>(sessionPool); sessionPool = null; GC.Collect(); GC.WaitForPendingFinalizers(); // Depending on the frameowrk version and the release mode, the pool may or may not be collected // at this point. If this weak reference has been cleared, we'll assume the internal one has been // as well. Otherwise, this test is pointless but harmless. if (!weakReference.TryGetTarget(out _)) { await client.Scheduler.RunAsync(TimeSpan.FromMinutes(10)); maintenanceCount = client.Logger.GetEntries(LogLevel.Debug).Count(entry => entry.Contains("maintenance")); // We're really just checking that at *some* point, we stopped logging. // If the maintenance loop hadn't stopped, we'd have 15 entries. Assert.InRange(maintenanceCount, 5, 8); } }
public async Task WaitForPoolAsync() { var client = new SessionTestingSpannerClient(); var options = new SessionPoolOptions { IdleSessionRefreshDelay = TimeSpan.FromMinutes(30), PoolEvictionDelay = TimeSpan.FromMinutes(30), MaintenanceLoopDelay = TimeSpan.FromMinutes(1), MinimumPooledSessions = 10, MaximumConcurrentSessionCreates = 20, WriteSessionsFraction = 0 }; var sessionPool = new SessionPool(client, options, client.Logger); // Ask when the pool is ready, which shouldn't take a minute. var poolReadyTask = sessionPool.WaitForPoolAsync(s_sampleDatabaseName, default); await client.Scheduler.RunAsync(TimeSpan.FromMinutes(1)); await poolReadyTask; // When the pool *is* ready, we should be able to acquire a session directly from the pool, // without any further delays. await sessionPool.AcquireSessionAsync(s_sampleDatabaseName, new TransactionOptions(), default); }