-
Notifications
You must be signed in to change notification settings - Fork 3
Defining Delegates
The delegate is defined using DefineDelegate(...)
method:
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder.DefineDelegate(delegateBuilder => { ... });
})
.Build()
.Run()
The delegates are executed as reaction on service lifecycle (routine or package) events. The stateful and stateless services define a rich set of events:
[Flags]
public enum StatefulServiceLifecycleEvent
{
// This service event occurs when replica initialization begins.
//
// All delegates are guaranteed to be executed before any of ICommunicationListeners is created.
//
// **WARNING**: All delegate does **not** have **write** access to reliable state.
OnStartup,
// This service event occurs when replica is changing roles.
//
// **WARNING**: All delegate does **not** have **write** access to reliable state.
OnChangeRole,
// This service event occurs when primary replica begins execution.
//
// All delegates are guaranteed to be executed after all ICommunicationListeners are opened.
// All delegates have **write** access to reliable state.
//
// **WARNING**: This event occurs every time replica is promoted to primary replica.
OnRun,
// This service event occurs when replica is shutting down.
//
// All delegates are guaranteed to be executed after all ICommunicationListeners are closed.
//
// **WARNING**: All delegate does **not** have **write** access to reliable state.
//
// **WARNING**: If event payload has IsAborting set to true then replica is terminated
// abnormaly and there no more guarantees.
OnShutdown,
// This service event occurs when replica detected data loss.
//
// Please see the official documentation:
// https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-backup-restore#restore
OnDataLoss,
// This service event occurs when replica state is restored.
//
// Please see the official documentation:
// https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicefabric.services.runtime.statefulservicebase.onrestorecompletedasync?view=azure-dotnet
OnRestoreCompleted,
// This service event occurs when code package is added to service package.
OnCodePackageAdded,
// This service event occurs when code package in service package is modified.
OnCodePackageModified,
// This service event occurs when code package is removed from service package.
OnCodePackageRemoved,
// This service event occurs when config package is added to service package.
OnConfigPackageAdded,
// This service event occurs when config package in service package is modified.
OnConfigPackageModified,
// This service event occurs when config package is removed from service package.
OnConfigPackageRemoved,
// This service event occurs when data package is removed to service package.
OnDataPackageAdded,
// This service event occurs when data package in service package is modified.
OnDataPackageModified,
// This service event occurs when data package is removed from service package.
OnDataPackageRemoved
}
[Flags]
public enum StatelessServiceLifecycleEvent
{
// This service event occurs when instance initialization begins.
//
// All delegates are guaranteed to be executed before any of ICommunicationListeners is created.
OnStartup,
// This service event occurs when instance begins execution.
//
// All delegates are guaranteed to be executed after all ICommunicationListeners are opened.
OnRun,
// This service event occurs when instance is shutting down.
//
// All delegates are guaranteed to be executed after all ICommunicationListeners are closed.
//
// **WARNING**: If event payload has IsAborting set to true then instance is terminated
// abnormally and there no more guarantees.
OnShutdown,
// This service event occurs when code package is added to service package.
OnCodePackageAdded,
// This service event occurs when code package in service package is modified.
OnCodePackageModified,
// This service event occurs when code package is removed from service package.
OnCodePackageRemoved,
// This service event occurs when config package is added to service package.
OnConfigPackageAdded,
// This service event occurs when config package in service package is modified.
OnConfigPackageModified,
// This service event occurs when config package is removed from service package.
OnConfigPackageRemoved,
// This service event occurs when data package is removed to service package.
OnDataPackageAdded,
// This service event occurs when data package in service package is modified.
OnDataPackageModified,
// This service event occurs when data package is removed from service package.
OnDataPackageRemoved
}
The event to react on is configured using UseEvent(...)
method:
...
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseEvent(/* event */);
})
...
By default the delegate is configured to react on StatefulServiceLifecycleEvent.OnRun
when configuring stateful service and StatelessServiceLifecycleEvent.OnRun
when configuring stateless service.
Information
The background jobs are configured as a reaction on
StatefulServiceLifecycleEvent.OnRun
andStatelessServiceLifecycleEvent.OnRun
events.
You also can configure multiple delegates to react on the same event:
...
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseEvent(StatefulServiceLifecycleEvent.OnRun);
})
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseEvent(StatefulServiceLifecycleEvent.OnRun);
})
...
... or you can configure the same delegate to react on multiple events:
...
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseEvent(
StatefulServiceLifecycleEvent.OnRun | StatefulServiceLifecycleEvent.OnShutdown);
})
...
Detailed information about the event can be obtained from invocation context. The type of the invocation context depends on the service type: it is IStatefulServiceDelegateInvocationContext
for stateful service and IStatelessServiceDelegateInvocationContext
for stateless service.
Invocation context has the information about the event and in some cases it can include additional payload about the event.
Context
public interface IStatefulServiceDelegateInvocationContextOnChangeRole
: IStatefulServiceDelegateInvocationContext
{
IStatefulServiceEventPayloadOnChangeRole Payload { get; }
}
Payload
public interface IStatefulServiceEventPayloadOnChangeRole
{
ReplicaRole NewRole { get; }
}
Context
public interface IStatefulServiceDelegateInvocationContextOnShutdown
: IStatefulServiceDelegateInvocationContext
{
IStatefulServiceEventPayloadOnShutdown Payload { get; }
}
Payload
public interface IStatefulServiceEventPayloadOnShutdown
{
// **true** indicates abnormal termination.
bool IsAborting { get; }
}
Context
public interface IStatefulServiceDelegateInvocationContextOnDataLoss
: IStatefulServiceDelegateInvocationContext
{
IStatefulServiceEventPayloadOnDataLoss Payload { get; }
}
Payload
public interface IStatefulServiceEventPayloadOnDataLoss
: IStatefulServiceDelegateInvocationContext
{
IStatefulServiceRestoreContext RestoreContext { get; }
}
// Allows to perform replica state restore from the backup.
//
// Please see the official documentation for more explanation:
// https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-backup-restore
public interface IStatefulServiceRestoreContext
{
Task RestoreAsync(
RestoreDescription restoreDescription);
Task RestoreAsync(
RestoreDescription restoreDescription,
CancellationToken cancellationToken);
}
Warning
If
RestoreAsync
completed successfully then underlying service will automatically report successful state restoration.
Contexts
public interface IStatefulServiceDelegateInvocationContextOnPackageAdded<TPackage>
: IStatefulServiceDelegateInvocationContext
{
IServiceEventPayloadOnPackageAdded<TPackage> Payload { get; }
}
public interface IStatefulServiceDelegateInvocationContextOnPackageModified<TPackage>
: IStatefulServiceDelegateInvocationContext
{
IServiceEventPayloadOnPackageModified<TPackage> Payload { get; }
}
public interface IStatefulServiceDelegateInvocationContextOnPackageRemoved<TPackage>
: IStatefulServiceDelegateInvocationContext
{
IServiceEventPayloadOnPackageRemoved<TPackage> Payload { get; }
}
Payloads
public interface IServiceEventPayloadOnPackageAdded<TPackage>
{
TPackage Package { get; }
}
public interface IServiceEventPayloadOnPackageModified<TPackage>
{
TPackage OldPackage { get; }
TPackage NewPackage { get; }
}
public interface IServiceEventPayloadOnPackageRemoved<TPackage>
{
TPackage Package { get; }
}
Warning
The
TPackage
is CodePackage, ConfigurationPackage or DataPackage.
Context
public interface IStatelessServiceDelegateInvocationContextOnShutdown
: IStatelessServiceDelegateInvocationContext
{
IStatelessServiceEventPayloadOnShutdown Payload { get; }
}
Payload
public interface IStatelessServiceEventPayloadOnShutdown
{
// **true** indicates abnormal termination.
bool IsAborting { get; }
}
Contexts
public interface IStatelessServiceDelegateInvocationContextOnPackageAdded<TPackage>
: IStatelessServiceDelegateInvocationContext
{
IServiceEventPayloadOnPackageAdded<TPackage> Payload { get; }
}
public interface IStatelessServiceDelegateInvocationContextOnPackageModified<TPackage>
: IStatelessServiceDelegateInvocationContext
{
IServiceEventPayloadOnPackageModified<TPackage> Payload { get; }
}
public interface IStatelessServiceDelegateInvocationContextOnPackageRemoved<TPackage>
: IStatelessServiceDelegateInvocationContext
{
IServiceEventPayloadOnPackageRemoved<TPackage> Payload { get; }
}
Payloads
public interface IServiceEventPayloadOnPackageAdded<TPackage>
{
TPackage Package { get; }
}
public interface IServiceEventPayloadOnPackageModified<TPackage>
{
TPackage OldPackage { get; }
TPackage NewPackage { get; }
}
public interface IServiceEventPayloadOnPackageRemoved<TPackage>
{
TPackage Package { get; }
}
Warning
The
TPackage
is CodePackage, ConfigurationPackage or DataPackage.
The action to execute is configured using UseDelegate(...)
method:
...
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseDelegate(() => { ... }));
})
...
This method can accept both synchronous i.e. Action<...>
and asynchronous Func<..., Task>
actions with up to fifteen parameters.
Information
All actions whose return type is different from
Task
orTask<>
are considered synchronous and their return values are ignored. All Action parameters are automatically populated using dependency injection
Asynchronous actions can require caller's CancellationToken
. The CancellationToken
can be obtained by adding additional CancellationToken
to action's parameter list:
...
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseDelegate(
(CancellationToken cancellationToken) => Task.Delay(Timeout.Infinite, cancellationToken));
}
)
...
In addition to CancellationToken
, UseDelegate(...)
supports direct injection of the event payload.
Warning
If delegate is configured to execute on multiple service event then direct payload injection will result in dependency injection error (because each payload is available only in scope of specific service event)
...
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseDelegate(
(IStatelessServiceEventPayloadOnShutdown eventPayload) => { ... }));
}
)
...
(c) 2021 Coherent Solutions Inc.
GENERAL
GETTING STARTED
UNDERSTANDING THE PROJECT
SAMPLES