public override async Task QueryStreamAsync( QueryEnvelope queryEnvelope, IServerStreamWriter <ResponseEnvelope> responseStream, ServerCallContext callContext ) { var streamPatterns = JsonConvert.DeserializeObject <string[]>(queryEnvelope.StreamPattern); try { var broker = new GrpcBroker(queryEnvelope); await Run(broker, responseStream, streamPatterns); } catch (Exception ex) { Log.ErrorException(ex, "Error running Rx query"); await ClientOnError(responseStream, ex); } }
public override async Task QueryStreamAsync( QueryEnvelope queryEnvelope, IServerStreamWriter <ResponseEnvelope> responseStream, ServerCallContext callContext) { try { var broker = new GrpcBroker(queryEnvelope); await Run(broker, responseStream); } catch (Exception ex) { await ClientOnError(responseStream, ex); throw; } }
private async Task Run(GrpcBroker broker, IServerStreamWriter <ResponseEnvelope> responseStream) { var isComplete = false; var isError = false; var eventCount = 0; using (var sub = broker.Observable.Subscribe( async e => await ClientOnNext(responseStream, e), async ex => await ClientOnError(responseStream, ex), async() => await ClientOnCompleted(responseStream))) { do { var @event = Activator.CreateInstance(broker.SourceType); broker.SourceType.GetProperty("CustomerId").SetValue(@event, Guid.NewGuid()); broker.SourceType.GetProperty("Email").SetValue(@event, "*****@*****.**"); broker.SourceType.GetProperty("PhoneNumber").SetValue(@event, "09-" + random.Next(0, 6)); broker.Observer.OnNext(@event); await Task.Delay(random.Next(0, 500)); if (eventCount++ > 5) { isComplete = random.Next(0, 20) == 0; isError = !isComplete && random.Next(0, 20) == 0; } } while (!isComplete && !isError); if (isComplete) { broker.Observer.OnCompleted(); } else if (isError) { broker.Observer.OnError(new Exception("Example error")); } } }
private async Task Run(GrpcBroker broker, IServerStreamWriter <ResponseEnvelope> responseStream, string[] streamPatterns) { var done = false; var position = new TFPos(); var operationId = Guid.NewGuid(); RxSubjectEnvelope envelope = null; void GetNextBatch(TFPos pos) { envelope = envelope ?? new RxSubjectEnvelope( broker.SourceType, broker.RegisteredTypes, broker.Observer, streamPatterns, GetNextBatch); var message = BuildMessage(operationId, envelope, pos); _publisher.Publish(message); } using (var sub = broker.Observable.Subscribe( async e => { try { await ClientOnNext(responseStream, e); } catch { done = true; } }, async ex => { await ClientOnError(responseStream, ex); done = true; }, async() => { await ClientOnCompleted(responseStream); done = true; }) ) { GetNextBatch(position); // TODO: Investiate the following // Waiting for completion this way isn't good but gRpc has an issue running inside // another thread via Task.Run or qbservable.RunAsync(): 'Response stream is already completed' while (!done) { await Task.Delay(25); } } }