netchkin netchkin - 1 month ago 15
C# Question

Cannot register two Actors within one ActorRuntime in Service Fabric

I have a single Service Fabric Actor Service. This creates two projects,

ActorService
and
ActorService.Interfaces
.

ActorService.Interfaces contains interface for the root actor, called
IRootActor
. ActorService itself contains
RootActor
and
IChildActor
,
ChildActor
. Both of the interfaces implement
IActor
, both of the classes inherit
Actor
and implement their respective interfaces. I register these actors from within Program.cs like this:

ActorRuntime.RegisterActorAsync<ChildActor>(
(context, actorType) => new ActorService(context, actorType, () => container.Resolve<ChildActor>()))
.GetAwaiter()
.GetResult();

ActorRuntime.RegisterActorAsync<RootActor>(
(context, actorType) => new ActorService(context, actorType, () => container.Resolve<RootActor.Factory>()(context)))
.GetAwaiter()
.GetResult();

Thread.Sleep(Timeout.Infinite);


The call to
container.Resolve<RootActor.Factory>()(context)
returns
RootActor
instance.

When I call

IRootActory proxy = ActorProxy.Create<IRootActor>(new ActorId(id), actorServiceUri);
proxy.Method(data);


everything goes fine. Aforementioned
RootActor.Method
method does two things in a single loop, creates child actor and calls it's method:

IChildActor proxy = ActorProxy.Create<IChildActor>(new ActorId(otherId), sameActorServiceUri);
proxy.OtherMethod(transformedData);


And here comes the problem. Upon
proxy.OtherMethod
call, essentially this wild exception appears:


HResult=-2146232969
Message=No MethodDispatcher is found for interface
id '230348154' Source=Microsoft.ServiceFabric.Actors


Am I doing something wrong here? Taking into account this SO thread, I thought it was possible to create two actors from one service...

Answer

Okay, I figured it out. For anyone out there struggling, the problem was with the actor service URI. I have wrongly assumed that both actors share service URI. As it was mentioned in the link I mentioned in the question, The actors get actually hosted separately. If you take a look inside ServiceManifest.xml, you'll find two Extension xml nodes, both of them named as __GeneratedServiceType__. All it takes is to change the service name part accoring to child DefaultService xml node, so in this example it would be most probably ChildActorService. Gosh, that sounds very inapropriate.

To wrap things up, the setup and configuration of anything in Service Fabric is rather complicated. However, VS tries it's best to help you out. Sometimes you don't even expect it, and here essentially lies the root of the evil. If you don't know what to look for, you won't look for it.

Comments