Open spingee opened 1 year ago
Bumping because I would also like to know if this functionality is currently possible. In v3 it was possible doing something like this library but I haven't figured out a way to do it in v7 since we no longer have access to IClientBuilder.Build()
.
Ok I found this response which claims that it's doable by having multiple hosts.
It also claims it's easier? Not sure how that would be the case now that you have to manage separate host lifetimes and separate service collections.
You don't necessarily need multiple hosts, but you do need multiple ServiceCollections
, one per client, and you would need to plumb the cross-cutting concerns (ILoggerFactory
, the ILogger<>
registration, etc) from the host to the client container, and then you'd need to register an IHostedService
in the host container to start the IHostedService
registered by the client.
I think an update to Orleans.MultiClient is the right approach, to essentially implement what I mentioned. In .NET 8, we will have Keyed DI in .NET itself, so it's possible that you could register the relevant IClusterClient
and IGrainFactory
instances with the host container that way.
Right, when I said hosts I guess I meant multiple IHost
s.
Is there a functional reason why this is an unsupported configuration? Does Orleans recommend against consuming multiple clusters?
Since with the v7 changes it seems like a design decision away from a configuration that was more possible previously when we had more control over ClientBuilder.
The old approach was just doing this anyway: the ClientBuilder
was effectively a HostBuilder
, creating/destroying its own container and starting a hosted service. It was confusing for people. The new approach is that you have a host (since you would have a host anyway for the vast majority of apps) and you add the client bits to it - no separate containers, no separate logging configuration, IConfiguration, no separate lifecycle management, etc.
The downside of this otherwise easier approach is that it's not as obvious how to create multiple clients in a single app. Creating multiple HostBuilders
is very close to creating multiple ClientBuilders
, even if it feels heavier. You have more control now, using the de-bundled approach.
All of this being said, we are open to the idea of having standalone clients or clients registered using Keyed DI (using the technique I mentioned above of referencing shared services across containers). This scenario seems common enough that having in-built support for it could be worthwhile.
@ReubenBond That makes sense. It does seem heavier just because as the consumer we're doing more work than we were before but I can see how that is simpler on your end and we get more flexibility overall.
I'm working on an implementation that does just that now - and one thing I'm missing is IClusterClient.Connect()
- is that not necessary anymore?
Here in the documentation it looks like both the v7
and v3
docs are referring to the old client builder when talking about a hosted service that handles connecting and closing.
@ReubenBond , is there anywhere we can get a sample of what the recommended approach is for creating clients? Especially external clients? The documentation mentions various ways but I think it would be good if the client portion had more details and a clear sample code. Especially for external clients as that is the more complicated one.
Is there any planned worked to use Keyed DI to support multiple clients?
@SoucianceEqdamRashti ClusterClient the internal Implementation of IClusterClient implement also IHostedService used to start and stop. So try to get IClusterCLient and try to cast it to IHostedService
We were migrating from 3.x to Orleans 8 and I faced this problem too 😞 Just if anyone is interested we used a frontend cluster talking to several backend clusters (silos). They are separate clusters because we deploy them independently and basically they are different versions of our app. So different versions of mobile clients were eventually talking to different backend clusters. This allowed smooth client releases and upgrades among different platforms.
We should make this easier... an add-on could achieve this with one DI container per client, and keyed DI to map the client back into the parent container. For example, it could work like so:
Would that fit the use cases here? This would not enable the creation of new clients at runtime but allows them to all be attached to a single host. If the creation of new clients at runtime is required, then that can be achieved with more effort, without the use of keyed DI. If there is a proposal for how people would like this to look & work, that would be very helpful
Yes we need creating clients in runtime. And our clustering configuration can change in runtime too, new cluster added, some old cluster removed etc. This makes implementation even harder because of client's lifetime control issues 😬
Hello, Is it possible to define multiple clients for differnet clusters in one appdomain/servicecolletion. Or another usecase we have localhost/inmemory orleans defined on IHost but want connect to real cluster with different client. Is this possible? Thanks for answer