Skip to content

Support deep Service Fabric integration #1059

@ReubenBond

Description

@ReubenBond

Service Fabric is a great platform for application hosting which offers high-density hosting, application upgrade, and state replication.

Many users, such as myself, would rather use Orleans than Service Fabric Reliable Actors. There are many reasons for this, including that Orleans is much more mature, open source, and feature rich.

We have integration packages for hosting Orleans atop Service Fabric. This integration is simple and effective but does not allow Orleans to gain all of the benefits which Service Fabric has to offer, such as collocated state.

Orleans should be the obvious choice for Virtual Actors in any hosting environment, so there is some additional work to be done which I would like insight into and assistance with.

This issue is for discussion and tracking of that work.

Basic Integration:

  • Hosting: Basic stateless, unpartitioned service hosting. Use the existing NuGet packages.

Integration Required for Collocated State:

  • Gateway Provider: Implement an IGatewayListProvider based on Service Fabric's NamingService. Added in Service Fabric cluster membership providers #2542
  • Cluster Membership Provider: Silos need to be discoverable by clients & each other. This should involve creating an IMembershipTable implementation which leverages Fabric's NamingService or PropertyService. This involves creating an IMembershipOracle implementation which can receive updates directly from Service Fabric in addition to periodically polling partitions. Added in Service Fabric cluster membership providers #2542
  • Grain Placement: Orleans should be partitioned and grain placement should deterministically map GrainId to partitions. Using consistent hashing means that we do not need to hold/maintain a grain directory. One potential downside to this approach is that we rely on the randomness of GrainIds to balance load across hosts and cannot perform load shedding in a granular fashion. This is mitigated by using a significant number of partitions, allowing Service Fabric to perform this load balancing at the partition level by shifting partitions between nodes based. This change requires only that we configure a new PlacementStrategy/PlacementDirector which resolves GrainId to SiloAddress based upon Service Fabric partitions. We can optionally eliminate the Grain Directory when we are using Service Fabric, but keeping the Grain Directory around allows us to use different placement strategies (as long as they are stateless or use a state provider which doesn't require consistent mapping between GrainId & Fabric partition.)
  • Partitioned hosting: This should only require a Service Fabric configuration change: Placement handles the important parts.
  • State Providers: deterministic grain placement allows us to use collocated, replicated state. State providers will be based upon IReliableDictionary<GrainId,byte[]>, using Service Fabric's Reliable Services model.

Extras:

  • Reminder Service: Reminder Services should be pluggable so that we can provide a Service Fabric-based reminder service.
  • Stream Provider: Service Fabric has an IReliableQueue<T> which can be used to produce an IStreamProvider.
  • Storage Provider: Collocated state requires the Grain Placement change, but we can also create a simple state service for in-cluster, non-collocated state. That would allow us to use the existing placement strategies.

General Work Which Would Help:

Much of this work would be much easier if dependency injection was used more pervasively throughout Orleans. There should not be a GatewayProviderType enum and there definitely should not be a GatewayProviderType.ZooKeeper value. Those things should be configured in a strongly typed manner.

Result:

Ultimately, this will give us integration which is on-par with Service Fabric's Reliable Actors implementation. We will also have all of the added features of Orleans.

Anything I've missed? Any obvious/subtle challenged which I may have overlooked?

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions