Паб/вспомогательный шаблон в Azure Service Fabric

Я работаю над приложением Azure Service Fabric здесь, где у меня есть определенные участники, которым нужно получить пинг/крючки из других сервисов по запросу. Приложение является своего рода механизмом распространения событий, который предназначен для работы примерно так:

  • Актер событий, который может принять событие, а затем позаботиться о распространении этого события для всех подписчиков этого типа событий.
  • 0..N участников подписки на события, которые каким-то образом должны сообщить маршрутизатору, какие типы событий они хотят подписаться, и как они хотят, чтобы они были доставлены (синхронизация или асинхронный).
  • Когда участник роутера события получает событие типа MyEvent, он будет определять, какие абоненты прослушивают и как они хотят, чтобы событие было доставлено. Для асинхронной доставки сообщение появится в теме Azure Service Bus. Тем не менее, для синхронной доставки актер маршрутизатора будет напрямую ссылаться на метод подписки на подписчиков, ожидая ответа.

Большая часть этого довольно прямолинейна, но я не совсем уверен, как я собираюсь снять синхронную доставку этих событий. Я не хочу, чтобы оператор-маршрутизатор событий каким-либо образом знал о каких-либо внутренних лицах в актерах, подписывающихся на события, но с текущими реализациями ActorProxy и тому подобное, имея доступ к интерфейсам, требуется для вызова методов для других участников.

Скажем, я подписываюсь на тип события, информируя маршрутизатор событий о том, что мой адрес fabric:/MyApp/MyEventSubscriberActor и что я хочу подписаться на MyEvent. Есть ли какой-либо разумный способ в API-интерфейсах Service Fabric, я могу программно вызывать метод для этого актера без (например, OnEventAsync(MyEvent ev) с помощью метода ActorProxy.Create<IMyEventSubscriberActor>()? Исходный код этих API не представляется общедоступным, поэтому я не имеют прямого способа проверить, как это делается под капотом.

Ответы

Ответ 1

Акт подписки на события может реализовать интерфейс подписки на события, содержащий метод "доступный событиям". Он может передать этот интерфейс методу "подписаться на событие" на интерфейсе актера маршрутизатора событий.

Интерфейс актера маршрутизатора событий может содержать ссылку на интерфейс подписки как часть его состояния. Когда событие, представляющее интерес для абонента, происходит, он может вызвать метод "доступный событиям" на интерфейсе, который он получил и сохранил ранее. Все это можно сделать без явного создания прокси-сервера актера для связи с актером подписки на события (инфраструктура сериализации актеров делает это под капотом).

Здесь очень простой пример, который опускает тип события, принимает только одного абонента и т.д., но должен дать вам представление о технике.

Интерфейсы:

interface IEventRouter : IActor
{
    void Subscribe(IEventSubscriber subscriber);
}

interface IEventSubscriber : IActor
{
    void EventAvailable();
}

Код подписчика события:

class EventSubscriber : Actor, IEventSubscriber
{
    void SubscribeToEvent()
    {
        IEventRouter router = ActorProxy.Create<IEventRouter>("fabric:/MyApp/MyEventRouterActor");
        router.Subscribe(this);
    }

    public void EventAvailable()
    {
        // Process the event
    }
}

Код маршрутизатора событий:

// Define actor state
[DataContract]
class RouterState
{
    [DataMember]
    public IEventSubscriber Subscriber;
}

// Define actor
class EventRouter : Actor<RouterState>, IEventRouter
{
    public void Subscribe(IEventSubscriber subscriber)
    {
        this.State.Subscriber = subscriber;
    }

    void OnEventAvailable()
    {
        this.State.Subscriber.EventAvailable();
    }
}