public async Task ReceiveAsync(IContext context) { switch (context.Message) { case Started _: Console.Out.WriteLine("Started: " + context.Self.Id); Actor.EventStream.Subscribe <ClusterTopologyEvent>(clusterTopologyEvent => { Console.Out.WriteLine("Got inner ClusterTopologyEvent"); context.Self.Tell(clusterTopologyEvent); }); break; case PID brokerPid: _brokers.Add(brokerPid); context.Watch(brokerPid); break; case Terminated terminated: _brokers.Remove(terminated.Who); context.Unwatch(terminated.Who); break; case ClusterTopologyEvent clusterTopologyEvent: Console.Out.WriteLine("clusterTopologyEvent"); _brokers.Clear(); foreach (MemberStatus memberStatus in clusterTopologyEvent.Statuses) { if (memberStatus.Alive) { PID remoteBrokerActorPid = new PID(memberStatus.Address, context.Self.Id); GetPublisherPiDsResponse getPublisherPiDsResponse = await remoteBrokerActorPid .RequestAsync <GetPublisherPiDsResponse>(new GetPublisherPiDs()) .ConfigureAwait(false); } } break; } }
public Task ReceiveAsync(IContext context) { switch (context.Message) { case Started _: _brokerMasterActor.Tell(context.Self); Props props = Actor.FromProducer(() => new PublisherActor()); foreach (int _ in Enumerable.Range(0, Environment.ProcessorCount)) { PID publisher = context.SpawnPrefix(props, nameof(PublisherActor)); context.Watch(publisher); _publisherActors.Add(publisher); } _clusterTopologyChangedSubscription = Actor.EventStream.Subscribe <ClusterTopologyEvent>(clusterTopologyEvent => { _brokerMasterActor.Tell(context.Self); }); break; case Stopped _: _clusterTopologyChangedSubscription?.Unsubscribe(); foreach (Subscription subscription in _subscriptions) { TellAll(new Unsubscribe { SubscriptionId = subscription.SubscriptionId }); } break; case GetPublisherPiDs _: GetPublisherPiDsResponse response = new GetPublisherPiDsResponse(); response.PIds.AddRange(_publisherActors); context.Respond(response); break; case Subscribe subscribe: Subscription newSubscription = new Subscription { SubscriptionId = ByteString.CopyFrom(Guid.NewGuid().ToByteArray()), Subscriber = subscribe }; _subscriptions.Add(newSubscription); TellAll(newSubscription); break; case Unsubscribe unsubscribe: _subscriptions.RemoveWhere(subscription => unsubscribe.SubscriptionId == subscription.SubscriptionId); TellAll(unsubscribe); break; case Terminated terminated: _publisherActors.Remove(terminated.Who); context.Unwatch(terminated.Who); break; } return(Task.CompletedTask); }
public ProtoBrokerSubject(PID brokerPid, string topic, string consumerGroup) { if (brokerPid == null) { throw new ArgumentNullException(nameof(brokerPid)); } _topic = topic ?? throw new ArgumentNullException(nameof(topic)); GetPublisherPiDsResponse getPublisherPiDsResponse = brokerPid.RequestAsync <GetPublisherPiDsResponse>(new GetPublisherPiDs()).Result; PID[] publishers = getPublisherPiDsResponse.PIds.ToArray(); int hash = Math.Abs(topic.GetHashCode()); _publisherPid = publishers[hash % publishers.Length]; _observable = Observable.Create <T>(async(observer, cancellationToken) => { try { Props props = Actor.FromProducer(() => new ConsumerActor <T>(observer)); PID consumerActor = Actor.SpawnPrefix(props, $"Consumer_{topic}_{consumerGroup}"); Subscribe addSubscription = new Subscribe { ConsumerActor = consumerActor, Topic = topic, Type = typeof(T).FullName }; List <SubscribeAck> subscriptions = new List <SubscribeAck>(); foreach (PID publisher in publishers.EmptyIfNull()) { SubscribeAck subscribeAck = await publisher .RequestAsync <SubscribeAck>(addSubscription) .ConfigureAwait(false); subscriptions.Add(subscribeAck); } try { await Task.Delay(-1, cancellationToken).ConfigureAwait(false); } finally { foreach (SubscribeAck subscription in subscriptions) { Unsubscribe removeSubscription = new Unsubscribe { SubscriptionId = subscription.SubscriptionId }; await Task.WhenAll(publishers .Select(publisher => publisher.RequestAsync <UnsubscribeAck>(removeSubscription))) .ConfigureAwait(false); } consumerActor.Stop(); } observer.OnCompleted(); } catch (OperationCanceledException) { observer.OnCompleted(); } catch (Exception e) { observer.OnError(e); } }) .Retry() .Publish() .RefCount(); }