tools - Pub/sub patrón en Azure Service Fabric
service fabric tutorial (1)
Estoy trabajando en una aplicación Azure Service Fabric aquí donde tengo ciertos actores que necesitan recibir pings / hooks de otros servicios a pedido. La aplicación es una especie de motor de distribución de eventos que está diseñado para funcionar de la siguiente manera:
- Un actor de enrutador de eventos que puede tomar un evento y luego distribuirlo a todos los suscriptores de ese tipo de evento.
- 0..N actores de suscripción de eventos que de alguna manera necesitan informar al enrutador a qué tipo de eventos desean suscribirse y cómo desean que se entreguen (sincronizados o asíncronos)
- Cuando el actor del enrutador de eventos recibe un evento del tipo
MyEvent
, identificará qué suscriptores están escuchando y cómo quieren que se entregue el evento. Para la entrega asíncrona, aparecerá un mensaje en un tema de Azure Service Bus. Sin embargo, para la entrega sincrónica, el actor del enrutador invocará el método de suscripción a los actores suscritos directamente, a la espera de su respuesta.
La mayor parte de esto es bastante sencillo, pero no estoy completamente seguro de cómo lograré la entrega sincrónica de estos eventos. No quiero que el actor del enrutador de eventos esté al tanto de ningún aspecto interno de los actores que se suscriben a los eventos; sin embargo, con las implementaciones actuales de ActorProxy
y similares, es necesario tener acceso a las interfaces para invocar métodos de otros actores.
Digamos que me suscribo a un tipo de evento, informando al enrutador de eventos que mi dirección es de fabric:/MyApp/MyEventSubscriberActor
y que quiero suscribirme a MyEvent
. ¿Existe alguna forma sensata dentro de las API de Service Fabric que pueda invocar un método en ese actor sin el método (por ejemplo, OnEventAsync(MyEvent ev)
usando el ActorProxy.Create<IMyEventSubscriberActor>()
? El código fuente de estas API no parece estar disponible públicamente, por lo que no tengo forma directa de verificar cómo se hace esto bajo el capó.
El actor de suscripción de eventos puede implementar una interfaz de suscripción de eventos que contenga un método de "evento disponible". Puede pasar esa interfaz a un método de "suscripción a evento" en la interfaz de actor de enrutador de eventos.
La interfaz del actor del enrutador de eventos puede mantener una referencia a la interfaz de suscripción como parte de su estado. Cuando ocurre el evento de interés para el suscriptor, puede llamar al método "evento disponible" en la interfaz que recibió y guardó anteriormente. Todo esto se puede hacer sin crear explícitamente un proxy de actor para comunicarse con el actor de suscripción del evento (la infraestructura de serialización de actores lo hace bajo el capó).
Este es un ejemplo muy básico que omite el tipo de evento, supone solo un suscriptor, etc., pero debería darle una idea de la técnica.
Interfaces:
interface IEventRouter : IActor
{
void Subscribe(IEventSubscriber subscriber);
}
interface IEventSubscriber : IActor
{
void EventAvailable();
}
Código de abonado del evento:
class EventSubscriber : Actor, IEventSubscriber
{
void SubscribeToEvent()
{
IEventRouter router = ActorProxy.Create<IEventRouter>("fabric:/MyApp/MyEventRouterActor");
router.Subscribe(this);
}
public void EventAvailable()
{
// Process the event
}
}
Código del enrutador del evento:
// 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();
}
}