internal static IReadOnlyList <Type> GetMessageTypesByAttributes(this IPublishMessageActor self) { return (Attribute.GetCustomAttributes(self.GetType()) .OfType <PublishMessageAttribute>() .Select(attr => attr.MessageType) .ToArray()); }
/// <summary> /// Removes all subscriptions of a given actor. /// </summary> /// <returns>True if <see cref="IActorRef" /> is not null.</returns> internal static bool RemoveFromSubscribers(this IPublishMessageActor self, IActorRef actor) { if (actor == null) { return(false); } foreach (var unsubscriber in self.Subscribers.Where(x => Equals(x.Item1, actor)).ToList()) { self.Subscribers.Remove(unsubscriber); } if (self.AutoWatchSubscriber) { self.ActorContext.Unwatch(actor); } return(true); }
/// <summary> /// Handles an <see cref="UnsubscribeMessage"/>. /// </summary> /// <param name="self">The <see cref="IPublishMessageActor"/></param> /// <param name="message">The <see cref="UnsubscribeMessage"/></param> /// <returns>True if <see cref="IActorRef"/> is removed from subscribers.</returns> internal static bool HandleUnsubscription(this IPublishMessageActor self, UnsubscribeMessage message) { self.HandleUnsubscriptionMessage(message); if (message.UnsubscribeAllTypes) { return(RemoveFromSubscribers(self, message.Unsubscriber)); } var result = self.Subscribers.Remove( self.Subscribers.FirstOrDefault( x => Equals(x.Item1, message.Unsubscriber) && x.Item2 == message.MessageType)); if (result && self.AutoWatchSubscriber) { self.ActorContext.Unwatch(message.Unsubscriber); } return(result); }
/// <summary> /// Publishes a message to all subscribers. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="self"></param> /// <param name="message"></param> /// <returns><b>false</b> if message is not in subscribable messages.</returns> public static bool PublishMessage <T>(this IPublishMessageActor self, T message) where T : class { var type = typeof(T); if (!self.SubscribableMessages.Contains(type)) { self.LogInfo("PublishMessage of Type {0} failed. Type not valid", type.Name); return(false); } var subscribers = self.Subscribers.Where(x => x.Item2 == type); foreach (var subscriber in subscribers) { subscriber.Item1.Tell(message); } return(true); }
/// <summary> /// Handles a <see cref="SubscribeMessage"/> /// </summary> /// <param name="self">The <see cref="IPublishMessageActor"/></param> /// <param name="message">The <see cref="SubscribeMessage"/></param> internal static void HandleSubscription(this IPublishMessageActor self, SubscribeMessage message) { self.HandleSubscriptionMessage(message); if (self.AutoWatchSubscriber) { self.ActorContext.Watch(message.Subscriber); } if (self.Subscribers.Any(x => Equals(x.Item1, message.Subscriber) && x.Item2 == message.MessageType)) { if (message.Confirmation) { message.Subscriber.Tell(new SubscribedMessage(true)); } return; } if (!self.SubscribableMessages.Contains(message.MessageType)) { if (message.Confirmation) { message.Subscriber.Tell(new SubscribedMessage(false)); } return; } self.Subscribers.Add(new Tuple <IActorRef, Type>(message.Subscriber, message.MessageType)); if (message.Confirmation) { message.Subscriber.Tell(new SubscribedMessage(true)); } }
/// <summary> /// Handles <see cref="Terminated"/>. /// </summary> /// <param name="self">The <see cref="IPublishMessageActor"/></param> /// <param name="message">The <see cref="Terminated"/></param> internal static void HandleTerminated(this IPublishMessageActor self, Terminated message) { self.HandleTerminationMessage(message); RemoveFromSubscribers(self, message.ActorRef); }