Obsolete |
---|
This post no longer contains latest information. Please refer to Service Fabric Handbook.
|
Hello,
Today I am happy to say – here is the first update to Service Fabric Handbook!
This update is about Stateful Service life-cycle.
Stateful Service Life Cycle
Stateful Service implementation isn’t just an instance of class
derived from StatefulServiceBase. When replica is build it’s implementation object is created and has to be initialized and correctly registered in the SF runtime.
There are three major life-cycle routines: Startup, Shutdown, Promotion and Demotion.
Pay attention that described life-cycles are slightly contradicts with the documentation. Please see issue on GitHub for details (why) and gist for code sample.
Author’s note
Startup
This routine is invoked when new replica is built.
Here is the sequence of events when implementation object is initialized as primary replica:
- Service’s implementation object is created.
- Service’s
OpenAsync
method is called and awaited. - Service’s
CreateServiceReplicaListeners
method is called and awaited. -
All
ServiceReplicaListener
‘s returned fromCreateServiceReplicaListeners
are used to create instances ofICommunicationListener
and have theirOpenAsync
methods called. The methods are called and awaited in sequence. - Service’s
ChangeRoleAsync
method is called (withnewRole = Primary
) and awaited. - Service’s
RunAsync
method is called.
When implementation object is initialized as secondary replica then the sequence of events is slightly different:
- Service’s implementation object is created.
- Service’s
OpenAsync
method is called and awaited. - Service’s
ChangeRoleAsync
method is called (withnewRole = IdleSecondary
) and awaited. - Service’s
CreateServiceReplicaListeners
method is called and awaited. -
All
ServiceReplicaListener
‘s whereServiceReplicaListener.ListenOnSecondary == true
return fromCreateServiceReplicaListeners
are used to create instances ofICommunicationListener
and have theirOpenAsync
methods called. The methods are called and awaited in sequence. - Service’s
ChangeRoleAsync
method is called (withnewRole = ActiveSecondary
) and awaited.
The differences in startup sequences can be explained according to replica roles and method purposes.
RunAsync
isn’t invoked on secondary replica-
The
RunAsync
method is designed to allows replica to perform some sort of background job. Because in Stateful Service only primary replica has write access to the reliable state then it doesn’t make sense to invoke this method in secondary replicas because primary and secondary replicas share the same implementation and would expect write access. ChangeRoleAsync
is invoked twice on secondary replica-
New secondary replica is always created in the
IdleSecondary
role because it should receive copy of the reliable state from the primary replica before this replica can be of any use. When copy of reliable state is received then replica continues the same startup sequence as primary replica with exceptions that final replica role is set toActiveSecondary
andRunAsync
method isn’t invoked.
The important moment to understand is when the startup routines are executed – when primary or secondary replica are initialized from scratch. The secondary replica can be initialized from scratch at any time when CM decides. In contrary to this primary replica is initialized from scratch only when partition is being initialized – in all other cases when CM requires to move primary replica then either existing secondary replica is promoted to primary or new secondary replica is initialized from scratch and then promoted to primary.
The partition initialization sequence is illustrated on the picture below:

Important to note that primary replica doesn’t call RunAsync
method until secondary replicas are built (i.e. have a copy of state). The amount of secondary replicas to await before running RunAsync
in primary replica is determined by MinReplicaSetSize
.
Promotion and Demotion
Promotion and demotion are natural part of Stateful Service partition life-cycle. These processes can happen for various reasons: primary replica movement (manual or automatic during resource balancing), primary replica failure, etc.
When secondary replica is promoted the following sequence of events is performed:
- All previously created
ICommunicationListener
have theirCloseAsync
method called and awaited. The methods are called and awaited in sequence. -
All
ServiceReplicaListener
‘s returned fromCreateServiceReplicaListeners
(during secondary replica initialization) are used to create instances ofICommunicationListener
and have theirOpenAsync
methods called and awaited. The methods are called and awaited in sequence. - Service’s
ChangeRoleAsync
method is called (withnewRole = Primary
) and awaited. - Service’s
RunAsync
method is called.
When primary replica is demoted the following sequence of events is performed:
- All previously created
ICommunicationListener
have theirCloseAsync
method called and awaited. The methods are called and awaited in sequence. CancellationToken
passed toRunAsync
method is canceled.RunAsync
method is awaited.-
All
ServiceReplicaListener
‘s returned fromCreateServiceReplicaListeners
(during primary replica initialization) whereServiceReplicaListener.ListenOnSecondary == true
are used to create instances ofICommunicationListener
and have theirOpenAsync
methods called and awaited. The methods are called and awaited in sequence. - Service’s
ChangeRoleAsync
method is called (withnewRole = ActiveSecondary
) and awaited.
Pay attention that
CreateServiceReplicaListeners
method isn’t called during promotion-demotion routines. The code uses the sameServiceReplicaListener
‘s returned from the first initialization.Author’s note
If the promotion-demotion cycle is graceful (i.e. it was triggered by CM) then at first primary replica is demoted and then secondary replica is promoted. In case of primary replica failure SF tires (if possible) to perform graceful shutdown or primary replica and in parallel executes promotion sequence on secondary replica.
Shutdown
Shutdown routine can be triggered by various reasons including replica restart or replica failure. The shutdown routine describes the so-called graceful shutdown (i.e. the process isn’t crashed and SF controls the process).
When primary replica is shutdown the following sequence of events is performed:
- All previously created
ICommunicationListener
have theirCloseAsync
method called and awaited. The methods are called and awaited in sequence. CancellationToken
passed to Service’sRunAsync
method is canceled.- Service’s
RunAsync
method is awaited. - Service’s
OnCloseAsync
method is called and awaited. - Service’s implementation object is destroyed.
When secondary replica is shutdown the following sequence of events is performed:
- All previously created
ICommunicationListener
have theirCloseAsync
method called and awaited. The methods are called and awaited in sequence. - Service’s
OnCloseAsync
method is called and awaited. - Service’s implementation object is destroyed.
Conclusion
This information is included into main Service Fabric Handbook blog post. Hope you enjoy reading 🙂
See you next time!