I'm working on an Azure Service Fabric application here where I have certain actors that need to receive pings/hooks from other services on demand. The application is a sort of event distribution engine that is intended to work something like this:
- An event router actor that can take an event in and then take care of distributing that event to all subscribers of that event type.
- 0..N event subscription actors that somehow need to inform the router what type of events they wish to subscribe to and how they want them delivered (sync or async).
- When the event router actor receives an event of the type
MyEvent
, it will identify what subscribers are listening and how they want the event delivered. For asynchronous delivery, a message will be popped in an Azure Service Bus topic. For synchronous delivery though, the router actor will invoke the subscription method on the subscribing actors directly, awaiting their response.
Most of this is fairly straight forward, but I'm not entirely sure how I'm going to pull off synchronous delivery of these events. I don't want the event router actor to in any way be aware of any internals in the actors subscribing to events - yet with the current ActorProxy
implementations and similar, having access to the interfaces are required to invoke methods on other actors.
Say I subscribe to an event type, informing the event router that my address is fabric:/MyApp/MyEventSubscriberActor
and that I want to subscribe to MyEvent
. Is there any sensible way within the Service Fabric APIs I can programatically invoke a method on that actor without (for instance OnEventAsync(MyEvent ev)
using the ActorProxy.Create<IMyEventSubscriberActor>()
method? The source code of these APIs doesn't seem to be publicly available, so I have no direct way of checking how this is done under the hood.
The event subscription actor can implement an event subscription interface that contains an "event-available" method. It can pass that interface to an "subscribe-to-event" method on the event router actor interface.
The event router actor interface can keep a reference to the subscription interface as part of its state. When the event of interest to the subscriber occurs, it can call the "event-available" method on the interface that it received and saved earlier. All of this can be done without explicitly creating an actor proxy to communicate with the event subscription actor (the actors serialization infrastructure does this under the hood).
Here's a very basic example that omits the event type, assumes just one subscriber etc., but should give you an idea of the technique.
Interfaces:
Event subscriber code:
Event router code: