示例#1
0
        public IObservable <IDeliveryArgs> GetResponses(DispatchArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (false == args.HasCorrelationId)
            {
                throw new ArgumentException($"{nameof(args)}.{nameof(args.CorrelationId)} is missing.");
            }

            if (0 == Interlocked.CompareExchange(ref _privateResponsesConnected, 1, 0))
            {
                _privateResponses.Connect();
            }

            return(Observable
                   .Create <IDeliveryArgs>(Subscribe)
                   .SubscribeOn(_privateEventLoopScheduler)
                   .Do(InspectAndLog)
                   .Where(IsIntentPermitted)
                   .ObserveOn(_privateEventLoopScheduler));


            IDisposable Subscribe(IObserver <IDeliveryArgs> observer)
            {
                observer = observer.NotifyOn(TaskPoolScheduler.Default);
                var subscription = Disposable.Create(() =>
                                                     _privateResponseObserversByCorrelationId.Remove(args.CorrelationId));

                try
                {
                    _privateResponseObserversByCorrelationId.TryAdd(args.CorrelationId, observer);
                    SendAsync(args);
                    return(subscription);
                }
                catch
                {
                    subscription.Dispose();
                    throw;
                }
            }

            bool IsIntentPermitted(IDeliveryArgs reply) =>
            _appInfo.IsExpectedReply(AppletId, args.IntentId, reply.IntentId);

            void InspectAndLog(IDeliveryArgs reply)
            {
                if (false == IsIntentPermitted(reply))
                {
                    Trace.TraceError(new StringBuilder("Unexpected Fan-Out response.")
                                     .Append($" Initiating applet: {AppletName}.")
                                     .Append($" Fan-Out request: {_appInfo.GetIntentName(args.IntentId)}.")
                                     .Append($" Fan-Out response: {reply.IntentName}.")
                                     .ToString()
                                     );
                }
            }
        }