Skip to content

Commit

Permalink
Add public available documentations to traits (#72)
Browse files Browse the repository at this point in the history
Added documentation for service factories, stateless instance, stateful
replica.
Replicator documentation is not public (yet), so only added minimal
information for them.
  • Loading branch information
youyuanwu authored Sep 26, 2024
1 parent 0eba9c9 commit d07bb9e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
46 changes: 37 additions & 9 deletions crates/libs/core/src/runtime/stateful.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ use crate::types::{LoadMetric, LoadMetricListRef, ReplicaRole};

use super::stateful_types::{Epoch, OpenMode, ReplicaInfo, ReplicaSetConfig, ReplicaSetQuarumMode};

/// Represents a stateful service factory that is responsible for creating replicas
/// of a specific type of stateful service. Stateful service factories are registered with
/// the FabricRuntime by service hosts via register_stateful_service_factory().
pub trait StatefulServiceFactory {
/// Called by Service Fabric to create a stateful service replica for a particular service.
fn create_replica(
&self,
servicetypename: &HSTRING,
Expand All @@ -24,28 +28,41 @@ pub trait StatefulServiceFactory {
) -> Result<impl StatefulServiceReplica, Error>;
}

// safe service instance
// The trait style is modeled by tonic server trait where send, sync and static are all required.
// This makes sure that bridge/proxy layer can work with rust async await easier.
/// Defines behavior that governs the lifecycle of a replica, such as startup, initialization, role changes, and shutdown.
/// Remarks:
/// Stateful service types must implement this interface. The logic of a stateful service type includes behavior that is
/// invoked on primary replicas and behavior that is invoked on secondary replicas.
#[trait_variant::make(StatefulServiceReplica: Send)]
pub trait LocalStatefulServiceReplica: Send + Sync + 'static {
// Note that open returns PrimaryReplicator instead of Replicator.
// The replicator that gives to SF has to implement primary replicator all the time.
// Ideally the return type should be Result<impl PrimaryReplicator>, but in bridge impl
// primary replicator needs to be stored in a ctx, but impl trait cannot be a variable type and anonymous.
// We cannot use rust async trait because dynamic dispatch is not yet supported.
/// Opens an initialized service replica so that additional actions can be taken.
/// Returns PrimaryReplicator that is used by the stateful service.
async fn open(
&self,
openmode: OpenMode,
partition: &StatefulServicePartition,
cancellation_token: CancellationToken,
) -> windows::core::Result<impl PrimaryReplicator>;

/// Changes the role of the service replica to one of the ReplicaRole.
/// Returns the service’s new connection address that is to be associated with the replica via Service Fabric Naming.
/// Remarks:
/// The new role is indicated as a parameter. When the service transitions to the new role,
/// the service has a chance to update its current listening address. The listening address is the address
/// where clients connect to it and the one returned via the ResolveAsync API. This enables the service when
/// it is a primary replica to only claim some resources such as ports when communication from clients is expected.
async fn change_role(
&self,
newrole: ReplicaRole,
cancellation_token: CancellationToken,
) -> ::windows_core::Result<HSTRING>; // replica address
) -> ::windows_core::Result<HSTRING>;

/// Closes the service replica gracefully when it is being shut down.
async fn close(&self, cancellation_token: CancellationToken) -> windows::core::Result<()>;

/// Ungracefully terminates the service replica.
/// Remarks: Network issues resulting in Service Fabric process shutdown
/// and the use of ReportFault(FaultType) to report a Permanent fault are examples of ungraceful termination.
/// When this method is invoked, the service replica should immediately release and clean up all references and return.
fn abort(&self);
}

Expand Down Expand Up @@ -75,6 +92,7 @@ impl From<&IFabricStatefulServicePartition> for StatefulServicePartition {
}
}

/// TODO: replicator has no public documentation
#[trait_variant::make(Replicator: Send)]
pub trait LocalReplicator: Send + Sync + 'static {
async fn open(&self, cancellation_token: CancellationToken) -> ::windows_core::Result<HSTRING>; // replicator address
Expand All @@ -85,6 +103,15 @@ pub trait LocalReplicator: Send + Sync + 'static {
role: &ReplicaRole,
cancellation_token: CancellationToken,
) -> ::windows_core::Result<()>;

/// (TODO: This doc is from IStateProvider but not Replicator.)
/// Indicates to a replica that the configuration of a replica set has changed due to
/// a change or attempted change to the primary replica. The change occurs due to failure
/// or load balancing of the previous primary replica. Epoch changes act as a barrier by
/// segmenting operations into the exact configuration periods in which they were sent
/// by a specific primary replica.
///
/// Called only on active secondary replicas. Primary replica gets new epoch via change_role call.
async fn update_epoch(
&self,
epoch: &Epoch,
Expand All @@ -95,6 +122,7 @@ pub trait LocalReplicator: Send + Sync + 'static {
fn abort(&self);
}

/// TODO: primary replicator has no public documentation
#[trait_variant::make(PrimaryReplicator: Send)]
pub trait LocalPrimaryReplicator: Replicator {
// SF calls this to indicate that possible data loss has occurred (write quorum loss),
Expand Down
21 changes: 19 additions & 2 deletions crates/libs/core/src/runtime/stateless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ impl StatelessServicePartition {
}
}

// safe factory
/// Stateless service factories are registered with the FabricRuntime by service hosts via
/// Runtime::register_stateless_service_factory().
///
pub trait StatelessServiceFactory {
/// Creates a stateless service instance for a particular service. This method is called by Service Fabric.
fn create_instance(
&self,
servicetypename: &HSTRING,
Expand All @@ -41,14 +44,28 @@ pub trait StatelessServiceFactory {
) -> windows_core::Result<impl StatelessServiceInstance>;
}

// safe service instance
/// Defines behavior that governs the lifecycle of a stateless service instance, such as startup, initialization, and shutdown.
#[trait_variant::make(StatelessServiceInstance: Send)]
pub trait LocalStatelessServiceInstance: Send + Sync + 'static {
/// Opens an initialized service instance so that it can be contacted by clients.
/// Remarks:
/// Opening an instance stateless service indicates that the service is now resolvable
/// and discoverable by service clients. The string that is returned is the address of this service instance.
/// The address is associated with the service name via Service Fabric naming and returned to
/// clients that resolve the service via resolve_service_partition(uri).
async fn open(
&self,
partition: &StatelessServicePartition,
cancellation_token: CancellationToken,
) -> windows::core::Result<HSTRING>;

/// Closes this service instance gracefully when the service instance is being shut down.
async fn close(&self, cancellation_token: CancellationToken) -> windows::core::Result<()>;

/// Terminates this instance ungracefully with this synchronous method call.
/// Remarks:
/// Examples of ungraceful termination are network issues resulting in Service Fabric process shutdown and the
/// use of ReportFault(FaultType) to report a Permanent fault. When the service instance receives this method,
/// it should immediately release and clean up all references and return.
fn abort(&self);
}

0 comments on commit d07bb9e

Please sign in to comment.