public void Notify(NotificationMessage notificationMessage) { var notificationId = ++_lastNotificationId; if (notificationId <= 0) notificationId = _lastNotificationId = 1; notificationMessage.NotificationId = notificationId; var sender = ActorCell.GetCurrentSelfOrNoSender(); Receiver.Tell(notificationMessage, sender); }
private void OnNotificationMessage(NotificationMessage notification) { object observerContext = null; if (notification.ObserverId != 0) { observerContext = EnsureObserverMap().GetContext(notification.ObserverId); if (observerContext == null) { // because it could be a removed observer, doesn't log anything. return; } } if (notification.InvokePayload == null) { Context.System.EventStream.Publish(new Event.Warning( Self.Path.ToString(), GetType(), $"Receives a bad notification with no payload from {Sender}")); return; } var payloadType = notification.InvokePayload.GetType(); var handlerItem = _handler.NotificationDispatcher.GetHandler(payloadType); if (handlerItem == null) { // if generic argument, try to instantiate a generic handler by the given payload type. if (payloadType.IsGenericType) { var genericHandlerItem = _handler.NotificationDispatcher.GetHandler(payloadType.GetGenericTypeDefinition()); if (genericHandlerItem != null) { handlerItem = genericHandlerItem.GenericHandlerBuilder(payloadType); _handler.NotificationDispatcher.AddHandler(payloadType, handlerItem); } } // oops, no handler. if (handlerItem == null) { Context.System.EventStream.Publish(new Event.Warning( Self.Path.ToString(), GetType(), $"Cannot find a handler for notification {notification.InvokePayload.GetType()} from {Sender}")); return; } } if (handlerItem.Handler != null) { // sync handle try { _observerContext = observerContext; handlerItem.Handler(this, notification); } finally { _observerContext = null; } } else { // async handle var context = new MessageHandleContext { Self = Self, Sender = base.Sender, CancellationToken = CancellationToken, ObserverContext = observerContext }; if (handlerItem.IsReentrant) { _activeReentrantCount += 1; } else { BecomeStacked(OnReceiveInAtomicTask); _currentAtomicContext = context; } using (new SynchronizationContextSwitcher(new ActorSynchronizationContext(context))) { handlerItem.AsyncHandler(this, notification) .ContinueWith(t => OnTaskCompleted(t.Exception, handlerItem.IsReentrant), TaskContinuationOptions.ExecuteSynchronously); } } }