protected override IStreamQueryDistributor CreateDistributor( Func<Lease, Task> onReceive = null, LeasableResource[] leasableResources = null, int maxDegreesOfParallelism = 5, string name = null, TimeSpan? waitInterval = null, string scope = null) { distributor = new InMemoryStreamQueryDistributor( leasableResources ?? DefaultLeasableResources, scope ?? DateTimeOffset.UtcNow.Ticks.ToString(), maxDegreesOfParallelism, waitInterval); if (onReceive != null) { distributor.OnReceive(onReceive); } return distributor; }
public async Task Competing_catchups_can_lease_a_partition_using_a_distributor() { var partitions = Enumerable.Range(0, 9) .Select(i => StreamQuery.Partition(i*100, (i + 1)*100)) .ToArray(); var store = new InMemoryProjectionStore<Projection<HashSet<int>, int>>(); var aggregator = Aggregator.CreateFor<HashSet<int>, int>((p, xs) => { if (p.Value == null) { p.Value = new HashSet<int>(); } foreach (var x in xs) { p.Value.Add(x); } }).Trace(); // set up 10 competing catchups for (var i = 0; i < 10; i++) { var distributor = new InMemoryStreamQueryDistributor( partitions.Select(p => new LeasableResource(p.ToString(), TimeSpan.FromSeconds(10))).ToArray(), "") .Trace(); distributor.OnReceive(async lease => { var partition = partitions.Single(p => p.ToString() == lease.LeasableResource.Name); var catchup = StreamCatchup.Create(await partitioner.GetStream(partition)); catchup.Subscribe(aggregator, store.Trace()); await catchup.RunSingleBatch(); }); distributor.Start(); disposables.Add(distributor); } partitions.ToList() .ForEach(partition => store.Should() .ContainSingle(p => p.Value.Count() == 100 && p.Value.OrderBy(i => i).Last() == partition.UpperBoundInclusive)); }