public SlowedEventHubContentLocationEventStore( ContentLocationEventStoreConfiguration configuration, IContentLocationEventHandler eventHandler, string localMachineName, CentralStorage centralStorage, AbsolutePath workingDirectory) : base(configuration, eventHandler, localMachineName, centralStorage, workingDirectory) { Contract.Requires(configuration is SlowedContentLocationEventStoreConfiguration); _configuration = (configuration as SlowedContentLocationEventStoreConfiguration) !; }
private static ContentLocationEventStore CreateEventStore( ContentLocationEventStoreConfiguration configuration, IContentLocationEventHandler eventHandler, string localMachineName, LocalDiskCentralStorage centralStorage, DisposableDirectory eventHubWorkingDirectory) { return(configuration switch { SlowedContentLocationEventStoreConfiguration _ => new SlowedEventHubContentLocationEventStore(configuration, eventHandler, localMachineName, centralStorage, eventHubWorkingDirectory.Path), _ => ContentLocationEventStore.Create(configuration, eventHandler, localMachineName, centralStorage, eventHubWorkingDirectory.Path), });
public Task ShutdownDoesNotProcessEnqueuedEvents() { // This test is "weird" in the sense that it relies on a "controlled" race condition. We need to check that // the master does not wait for events to finish processing to complete its shutdown. The way we do this is // force an arbitrary delay when processing events, and then make sure that we haven't processed any after // shutdown. // // * If we do it with a cancellation token on shutdown started, then we have a race condition, because the // token will be triggered, and the item could be processed before shutdown finishes. // * If we do it with a separate lock, we'll need some sort of delay which will be equivalent to what we do // now. // * We can't use a cancellation token on shutdown finished, because shutdown awaits for the action blocks // to complete, and this means we have a deadlock. // // By doing things this way, we are relying on the fact that it is unlikely for a thread to not run for a // second. If we assume that's true, then the slowdown will resume after shutdown has started waiting, and // we will do the appropriate fast-return path. var configuration = new SlowedContentLocationEventStoreConfiguration() { Slowdown = TimeSpan.FromSeconds(1) }; var eventHandler = new TestEventHandler(); return(WithContentLocationEventStore(async(tracingContext, clock, fileSystem, eventStore) => { var context = new OperationContext(tracingContext); var sequencePoint = new EventSequencePoint(clock.UtcNow); eventStore.StartProcessing(context, sequencePoint).ShouldBeSuccess(); eventStore.AddLocations(context, MachineId.FromIndex(0), new[] { new ContentHashWithSize(ContentHash.Random(), 1) }).ShouldBeSuccess(); (await eventStore.ShutdownAsync(context)).ShouldBeSuccess(); eventHandler.EventsHandled.Should().Be(0); }, configuration, eventHandler)); }