What seems to be just common practice could be the wrong thing to do in Service Fabric. I suspect the below code where stateManager is saved as local cache could cause a potential issue when the 'Startup' class is instantiated within the return statement of 'CreateServiceReplicaListeners()' method in 'SomeService' stateful service.
The situation that can happen is when the state manager is somehow re-instantiated. I need more explanation as to whether the below practice is the right thing to do or not. If not, what could be the best practice instead?
internal class SomeService : StatefulService
{
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[]{
new ServiceReplicaListener(
initParams =>
new OwinCommunicationListener("SomeService", new Startup(this.StateManager), initParams))
};
}
}
}
public class Startup : IOwinAppBuilder
{
private readonly IReliableStateManager stateManager;
public Startup(IReliableStateManager stateManager)
{
this.stateManager = stateManager;
}
public void Configuration(IAppBuilder appBuilder)
{
// other initialization codes..
...
...
UnityConfig.RegisterComponents(config, this.stateManager);
appBuilder.UseWebApi(config);
}
}
Whenever a Stateful Service change roles it triggers a IStatefulServiceReplica.ChangeRoleAsync(ReplicaRole newRole, CancellationToken cancellationToken)
.
ChangeRoleAsync(..)
ensure that the new role uses the correct communications doing the following:
CloseCommunicationListenersAsync(CancellationToken cancellationToken)
to close any listeners openOpenCommunicationListenersAsync(newRole, cancellationToken)
for Primary or ActiveSecondary rolesOpenCommunicationListenersAsync()
will call CreateServiceReplicaListeners()
to get the listeners and call CreateCommunicationListener(serviceContext)
for each returned listener to open the related endpoints.Change of Roles is very common to happen during upgrades and Load Balancing, so this is a very common event.
In Summary,
Every time a Change of Role happens, CreateServiceReplicaListeners()
will be called, ChangeRole does not shutdown the service, so it might have side effects, for example if you register dependencies in a DI container, you might face duplicate registrations.