Microsoft Orleans — Code Generation issue?

While working on the post “Microsoft Orleans — Reporting Dashboard”, I ran into an issue where code generation seemingly stopped “generating”.

Here’s a compare of when Code Generation was working (pre the start of previously stated post), and when it stopped working while writing the post:

As you can see, not much had changed between the two, but for whatever reason, the SiloHost stopped being able to instantiate instances of my grains, or at a minimum the Client was saying that the SiloHost couldn’t.

When the issue is not present (like in commit), running the application looks like:

When It is present, (like in commit) it looks like:

I have opened a GitHub issue to try to get clarification on what I’m experiencing; but in the meantime, there is a workaround.


The Workaround

I was under the impression that projects containing the Microsoft.Orleans.OrleansCodeGenerator.Build NuGet package would automatically run code generation, though that didn’t seem to always be the case as per the github issue I submit above.

In order to get around the code generation not firing, I took a few different steps. (Note, I’m guessing some of these steps could be omitted, but I just mostly tried to brute force it, and once it was working left it alone):

  • Utilize the .ConfigureApplicationParts method on both the ClientBuilder and SiloBuilder.
  • Have grain interfaces implement an empty interface, for registration within the ClientBuilder.
  • Have grain implementations implement an empty interface, for registration within the SiloBuilder.

Grains/Grain Interface changes

The interface I used for the grain interfaces, was created under Kritner.OrleansGettingStarted.GrainInterfaces:

public interface IGrainInterfaceMarker { }

The grain implementation interface was created under Kritner.OrleansGettingStarted.Grains:

public interface IGrainMarker { }

The grain interfaces I have — IHelloWorld, and IVisitTracker were updated to additionally implement IGrainInterfaceMarker. The same was done for the grain implementations, but implement IGrainMarker.


ClientBuilder and SiloHostBuilder Updates

Now that our grains and interfaces are implementing their new respective interface markers, we just need to register those interface types on the ClientBuilder and SiloHostBuilder as so:

ClientBuilder:

.ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(IGrainInterfaceMarker).Assembly).WithReferences())

SiloHostBuilder:

.ConfigureApplicationParts(parts =>
{
parts.AddApplicationPart(typeof(IGrainMarker).Assembly).WithReferences();
})

Now that these changes have been made, the grains are being successfully called on the cluster from the client! Hooray!

The commit where this correction was put in place is located here: https://github.com/Kritner-Blogs/OrleansGettingStarted/pull/6/commits/9c271f085d22a66f8e8d3c3165eda863e5269508


GitHub Issue

I heard back from Sergey in the GitHub Issue:

Basically putting in the Orleans Dashboard, effectively turned off the “automatic scanner” I was taking advantage of previously. The act of adding the Orleans Dashboard called into AddApplicationPart, under the covers, which in turn turned off automatic scanning. I guess the reasoning behind this was “the developer is registering something (even though it was Orleans Dashboard), so there’s no need to do automatic scanning for the grains to be picked up.