private async Task BasicScenario(bool enabled) { var options = new ClusterMembershipOptions { DefunctSiloCleanupPeriod = enabled ? new TimeSpan?(TimeSpan.FromMinutes(90)) : null, DefunctSiloExpiration = TimeSpan.FromDays(1) }; var timers = new List <DelegateAsyncTimer>(); var timerCalls = new ConcurrentQueue <(TimeSpan?DelayOverride, TaskCompletionSource <bool> Completion)>(); var timerFactory = new DelegateAsyncTimerFactory( (period, name) => { Assert.Equal(options.DefunctSiloCleanupPeriod.Value, period); var t = new DelegateAsyncTimer( overridePeriod => { var task = new TaskCompletionSource <bool>(); timerCalls.Enqueue((overridePeriod, task)); return(task.Task); }); timers.Add(t); return(t); }); var table = new InMemoryMembershipTable(); var cleanupAgent = new MembershipTableCleanupAgent( Options.Create(options), table, this.loggerFactory.CreateLogger <MembershipTableCleanupAgent>(), timerFactory); var lifecycle = new SiloLifecycleSubject(this.loggerFactory.CreateLogger <SiloLifecycleSubject>()); ((ILifecycleParticipant <ISiloLifecycle>)cleanupAgent).Participate(lifecycle); await lifecycle.OnStart(); Assert.DoesNotContain(table.Calls, c => c.Method.Equals(nameof(IMembershipTable.CleanupDefunctSiloEntries))); Assert.Equal(enabled, timerCalls.TryDequeue(out var timer)); timer.Completion?.TrySetResult(true); var stopped = lifecycle.OnStop(); while (timerCalls.TryDequeue(out timer)) { timer.Completion.TrySetResult(false); } if (enabled) { Assert.Contains(table.Calls, c => c.Method.Equals(nameof(IMembershipTable.CleanupDefunctSiloEntries))); } else { Assert.DoesNotContain(table.Calls, c => c.Method.Equals(nameof(IMembershipTable.CleanupDefunctSiloEntries))); } await stopped; }
/// <summary> /// Returns a correct implementation of the persistence provider according to environment variables. /// </summary> /// <remarks>If the environment invariants have failed to hold upon creation of the storage provider, /// a <em>null</em> value will be provided.</remarks> public async Task <IGrainStorage> GetStorageProvider(string storageInvariant) { //Make sure the environment invariants hold before trying to give a functioning SUT instantiation. //This is done instead of the constructor to have more granularity on how the environment should be initialized. try { using (await StorageLock.LockAsync()) { if (AdoNetInvariants.Invariants.Contains(storageInvariant)) { if (!StorageProviders.ContainsKey(storageInvariant)) { Storage = Invariants.EnsureStorageForTesting(Invariants.ActiveSettings.ConnectionStrings.First(i => i.StorageInvariant == storageInvariant)); var options = new AdoNetGrainStorageOptions() { ConnectionString = Storage.Storage.ConnectionString, Invariant = storageInvariant }; var clusterOptions = new ClusterOptions() { ServiceId = Guid.NewGuid().ToString() }; var storageProvider = new AdoNetGrainStorage(DefaultProviderRuntime.ServiceProvider.GetService <ILogger <AdoNetGrainStorage> >(), DefaultProviderRuntime, Options.Create(options), Options.Create(clusterOptions), storageInvariant + "_StorageProvider"); ISiloLifecycleSubject siloLifeCycle = new SiloLifecycleSubject(NullLoggerFactory.Instance.CreateLogger <SiloLifecycleSubject>()); storageProvider.Participate(siloLifeCycle); await siloLifeCycle.OnStart(CancellationToken.None); StorageProviders[storageInvariant] = storageProvider; } } } } catch { StorageProviders.Add(storageInvariant, null); } return(StorageProviders[storageInvariant]); }