/// <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);
        }