public void ComplexScrollAllObservable() { int numberOfSlices = Environment.ProcessorCount; var scrollAllObservable = Client.ScrollAll <Project>("10s", numberOfSlices, sc => sc .MaxDegreeOfParallelism(numberOfSlices) .Search(s => s .Query(q => q .Term(f => f.State, StateOfBeing.Stable) ) ) ); var waitHandle = new ManualResetEvent(false); ExceptionDispatchInfo info = null; var scrollAllObserver = new ScrollAllObserver <Project>( onNext: response => ProcessResponse(response.SearchResponse), // <1> do something with the response onError: e => { info = ExceptionDispatchInfo.Capture(e); // <2> if an exception is thrown, capture it to throw outside of the observer waitHandle.Set(); }, onCompleted: () => waitHandle.Set() ); scrollAllObservable.Subscribe(scrollAllObserver); // <3> initiate scrolling waitHandle.WaitOne(); // <4> block the current thread until the wait handle is set info?.Throw(); // <5> if an exception was captured whilst scrolling, throw it }
private void ScrollAll(string index, int numberOfShards, int numberOfDocuments) { var handle = new ManualResetEvent(false); var scrollObservable = this._client.ScrollAll <SmallObject>("1m", numberOfShards, s => s .MaxDegreeOfParallelism(numberOfShards / 2) .Search(search => search .Index(index) .AllTypes() .MatchAll() ) ); //we set up an observer var seenDocuments = 0; var seenSlices = new ConcurrentBag <int>(); //since we call allTypes search should be bounded to index. var scrollObserver = new ScrollAllObserver <SmallObject>( onError: (e) => { handle.Set(); throw e; }, onCompleted: () => handle.Set(), onNext: (b) => { seenSlices.Add(b.Slice); Interlocked.Add(ref seenDocuments, b.SearchResponse.Hits.Count); } ); //when we subscribe the observable becomes hot scrollObservable.Subscribe(scrollObserver); handle.WaitOne(TimeSpan.FromMinutes(5)); seenDocuments.Should().Be(numberOfDocuments); var groups = seenSlices.GroupBy(s => s).ToList(); groups.Count().Should().Be(numberOfShards); groups.Should().OnlyContain(g => g.Count() > 1); }