Support adding cluster clients to an app's IServiceCollection
- 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
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