dotnet / dotnet/orleans

Support adding cluster clients to an app's IServiceCollection

Open
#4,744 7 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
C#
Stars
10.9k
Forks
2.1k
Avg merge
14h 42m
Merged PRs (30d)
354

Description

Since most modern frontends user either ASP.NET (Mvc or WebApi) and with the new generic Host that was shipped in Microsoft.Extensions.Hosting 2.1, we can expect most Orleans clients will be using the `IServiceCollection` abstraction for building their frontend hosts.
It would be good to provide a simple way to configure an `IClusterClientFactory` that can build 1 or more cluster clients. This can benefit from passing the cross-cutting services configured in the app's container into each of the `IClusterClient`s that get built.
In particular for now, pass in the logger factory and the host's configuration (whatever config providers that were configured using Microsoft.Extensions.Configuration), and potentially then use Polly for connection retries, etc.

Note that I'm explicitly not suggesting we should share the app's container with the IClusterClient(s), but instead share it with the factory and keep the cluster client's container as an internal implementation that is isolated from the app's container or lifecycle.

We can use [HttpClientFactory as an inspiration](https://github.com/aspnet/HttpClientFactory/blob/master/samples/HttpClientFactorySample/Program.cs).

Then, configuring an Orleans cluster client factory would be a matter of calling an extension method on an `IServiceCollection` and configuring the client (or named clients) normally, except without explicitly configuring Logging or Configuration.

```
// ... configure MVC, logging, etc in a generic Host

services.AddClusterClient("some client identifier", c =>
{
c.UseAzureStorageClustering(...)
c.Configure(options =>
{
options.ClusterId = "dev";
options.ServiceId = "HelloWorldApp";
});
});
```
Of course we can also support a default (non-named) client.

Then you can just inject the `IClusterClientFactory` in your app code to get a hold of a particular client (or just inject the `IClusterClient` if it was registered as default.
The factory can also act as a hosted service (if using the generic Host) to gracefully shutdown all the clients when the host is shutting down.

For reasons why I don't advocate sharing the container, 1 is obvious: it would make the assumption that a client library must be configured in the same way as the app host, and it wouldn't even support multiple clients. For others, there's [this longer chat thread](https://gitter.im/dotnet/orleans?at=5b3e746370efc60660b06f0f) with @galvesribeiro

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the proposed IServiceCollection extension and IClusterClientFactory design, using the linked HttpClientFactory sample as the stated inspiration. Define how named and default clients receive the host logger factory and configuration while retaining isolated containers, then verify graceful shutdown through the generic Host.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
distributed-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.