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);
            }
        }
Exemple #2
0
        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;
            }
        }
Exemple #3
0
        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);
                }
            }
        }