/// <summary> /// Converts the source sequence to <see cref="ResourceEventDeltaBlock{TKey,TResource}"/>. This transitions from /// observable into TPL Dataflow monad. The resulting block allows queue processing semantics where each resulting item /// is the collection of the given <see cref="ResourceEvent{TResource}"/> for grouped by resource object identified by the /// <paramref name="keySelector"/> parameter /// </summary> /// <param name="source">The resource observable</param> /// <param name="keySelector">Key selector function that uniquely identifies objects in the resource collection being observed</param> /// <typeparam name="TResource">The type of resource</typeparam> /// <typeparam name="TKey">The key for the resource</typeparam> /// <returns>The <see cref="ResourceEventDeltaBlock{TKey,TResource}"/> connected to the observable</returns> public static ISourceBlock <List <ResourceEvent <TResource> > > ToResourceEventDeltaBlock <TKey, TResource>(this IObservable <ResourceEvent <TResource> > source, Func <TResource, TKey> keySelector, out IDisposable subscription) { var deltaBlock = new ResourceEventDeltaBlock <TKey, TResource>(keySelector); subscription = source.Subscribe(deltaBlock.AsObserver()); return(deltaBlock); }
public async Task DistributeWork(string description, ScheduledEvent <TestResource>[] events, ResourceEvent <TestResource>[][] expected) { _log.LogInformation(description); var sut = new ResourceEventDeltaBlock <int, TestResource>(x => x.Key); var testScheduler = new TestScheduler(); var results = new List <List <ResourceEvent <TestResource> > >(); var actionBlock = new ActionBlock <List <ResourceEvent <TestResource> > >(deltas => { _log.LogTrace($"Worker called for {string.Join("",deltas)}"); results.Add(deltas); testScheduler.Sleep(300); }, new ExecutionDataflowBlockOptions() { BoundedCapacity = 1, MaxDegreeOfParallelism = 1 }); sut.LinkTo(actionBlock, new DataflowLinkOptions { PropagateCompletion = true }); events.ToTestObservable(testScheduler, logger: _log).Subscribe(sut.AsObserver()); await actionBlock.Completion.TimeoutIfNotDebugging(); results.Should().BeEquivalentTo(expected); }