Exemple #1
0
 private void OnUnsubscribed(DateTime lastOriginatingTime)
 {
     this.source = null;
     foreach (var handler in this.unsubscribedHandlers)
     {
         this.scheduler.Schedule(this.syncContext, PipelineElement.TrackStateObjectOnContext(() => handler(lastOriginatingTime), this.Owner, this.pipeline), lastOriginatingTime, false, true);
     }
 }
Exemple #2
0
 internal Receiver(object owner, Action <Message <T> > onReceived, SynchronizationLock context, Pipeline pipeline, bool enforceIsolation = false)
 {
     this.scheduler        = pipeline.Scheduler;
     this.onReceived       = PipelineElement.TrackStateObjectOnContext <Message <T> >(onReceived, owner, pipeline);
     this.owner            = owner;
     this.syncContext      = context;
     this.enforceIsolation = enforceIsolation;
     this.cloner           = RecyclingPool.Create <T>();
     this.pipeline         = pipeline;
 }
Exemple #3
0
        private void OnUnsubscribed(DateTime lastOriginatingTime)
        {
            this.pipeline.DiagnosticsCollector?.PipelineElementReceiverUnsubscribe(this.pipeline, this.element, this, this.source);
            foreach (var handler in this.unsubscribedHandlers)
            {
                PipelineElement.TrackStateObjectOnContext(() => handler(lastOriginatingTime), this.Owner, this.pipeline).Invoke();
            }

            // clear the source only after all handlers have run to avoid this node being finalized prematurely
            this.source = null;
        }
Exemple #4
0
        /// <inheritdoc />
        public void Close(DateTime originatingTime)
        {
            if (this.lastEnvelope.SequenceId != int.MaxValue)
            {
                var e = this.CreateEnvelope(originatingTime);
                e.SequenceId = int.MaxValue; // special "closing" ID
                this.Deliver(new Message <T>(default(T), e));

                this.receivers = new Receiver <T> [0];

                foreach (var handler in this.closedHandlers)
                {
                    PipelineElement.TrackStateObjectOnContext(() => handler(originatingTime), this.Owner, this.pipeline).Invoke();
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EventSource{TEventHandler, TOut}"/> class.
        /// The component will subscribe to an event on startup via the <paramref name="subscribe"/>
        /// delegate, using the supplied <paramref name="converter"/> function to transform the
        /// <see cref="Post"/> action delegate into an event handler compatible with the external
        /// event that is being subscribed to.
        /// </summary>
        /// <param name="pipeline">The Psi pipeline.</param>
        /// <param name="subscribe">The delegate that subscribes to the external event.</param>
        /// <param name="unsubscribe">The delegate that unsubscribes from the external event.</param>
        /// <param name="converter">
        /// A function used to convert the <see cref="Post"/> action delegate into an event
        /// handler of type <typeparamref name="TEventHandler"/> that will be subscribed to the
        /// external event by the <paramref name="subscribe"/> delegate.
        /// </param>
        public EventSource(
            Pipeline pipeline,
            Action <TEventHandler> subscribe,
            Action <TEventHandler> unsubscribe,
            Func <Action <TOut>, TEventHandler> converter)
        {
            this.pipeline    = pipeline;
            this.Out         = pipeline.CreateEmitter <TOut>(this, nameof(this.Out));
            this.subscribe   = subscribe;
            this.unsubscribe = unsubscribe;

            // If the source event is triggered from the execution context of some other receiver, then because the
            // execution context flows all the way through to the event handler, the tracked state object (if tracking
            // is enabled) would represent the owner of the receiver, which would be inconsistent with posting from a
            // pure source (no tracked state object). In order to rectify this, we set the tracked state object to null
            // just prior to the call to this.Post by wrapping it in TrackStateObjectOnContext with a null state object.
            this.eventHandler = converter(PipelineElement.TrackStateObjectOnContext <TOut>(this.Post, null, pipeline));
        }
Exemple #6
0
 internal Receiver(int id, string name, PipelineElement element, object owner, Action <Message <T> > onReceived, SynchronizationLock context, Pipeline pipeline, bool enforceIsolation = false)
 {
     this.scheduler        = pipeline.Scheduler;
     this.schedulerContext = pipeline.SchedulerContext;
     this.lastEnvelope     = default;
     this.onReceived       = m =>
     {
         this.lastEnvelope = m.Envelope;
         PipelineElement.TrackStateObjectOnContext(onReceived, owner, pipeline)(m);
     };
     this.Id                           = id;
     this.Name                         = name;
     this.element                      = element;
     this.Owner                        = owner;
     this.syncContext                  = context;
     this.enforceIsolation             = enforceIsolation;
     this.Recycler                     = RecyclingPool.Create <T>();
     this.pipeline                     = pipeline;
     this.receiverDiagnosticsCollector = new Lazy <DiagnosticsCollector.ReceiverCollector>(() => this.pipeline.DiagnosticsCollector?.GetReceiverDiagnosticsCollector(pipeline, element, this), true);
 }