grpc-dotnet icon indicating copy to clipboard operation
grpc-dotnet copied to clipboard

Change Client address at runtime

Open adamradocz opened this issue 2 years ago • 9 comments

Hi,

I'm using ASP.NET Core on .NET 6 framework. The client factory is configured in the DIC and the address is passed by the IOptionMonitor. When the configuration is updated I'm still getting the a client from the DIC with the old address.

How should I handle a scenario in runtime when the server address is changed?

Thanks!

adamradocz avatar Mar 17 '22 15:03 adamradocz

Could you give a code sample of what you're doing with IOptionMonitor and the address? Are you using this approach with other configuration and updating IOptionMonitor does work?

JamesNK avatar Mar 18 '22 23:03 JamesNK

Here's a sample code. The second client still uses the same channel even though the clientOptions contains the new address. Do you want me to upload the sample project?

using GrpcClient.Models;
using GrpcServer;
using Microsoft.Extensions.Options;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddGrpc();
builder.Services.Configure<ClientOptions>(builder.Configuration.GetSection(nameof(ClientOptions)));

builder.Services.AddGrpcClient<Greeter.GreeterClient>((serviceProvider, factoryOptions) => 
{
    var clientOptions = serviceProvider.GetRequiredService<IOptionsMonitor<ClientOptions>>();
    factoryOptions.Address = clientOptions.CurrentValue.ServerAddress;
});


var app = builder.Build();

// Current client
var clientOptions = app.Services.GetRequiredService<IOptionsMonitor<ClientOptions>>();
app.Logger.LogInformation("Address: {Address}", clientOptions.CurrentValue.ServerAddress);
var client = app.Services.GetRequiredService<Greeter.GreeterClient>();

// Waiting to change the Uri in the appsettings.json
app.Logger.LogInformation("Waiting for 30 seconds...");
await Task.Delay(TimeSpan.FromSeconds(30));

// New client
app.Logger.LogInformation("Address: {Address}", clientOptions.CurrentValue.ServerAddress);
var newClient = app.Services.GetRequiredService<Greeter.GreeterClient>();

app.Run();

adamradocz avatar Mar 21 '22 13:03 adamradocz

@JamesNK any news about this?

adamradocz avatar Apr 27 '22 19:04 adamradocz

No. There aren't any plans to do this right now.

.NET features that use configuration generally use a snapshot of those settings when they start. Few support runtime changes. It would be a significant amount of work to change the gRPC client factory to support it, so we'll probably only do it if there is a lot of community interest in this feature.

For advanced scenarios like this, I suggest managing a channel and client in custom code and not using gRPC client factory.

JamesNK avatar Apr 27 '22 23:04 JamesNK

I have an application that would benefit from this capability.

Is there no way to restart the client service when detecting a change using Options Monitor?

a-priestley avatar Dec 13 '23 12:12 a-priestley

Well, I just came to the issues page to post the same question and saw that one already existed. My use case would be to allow the user to set the server address via a text box in a UI, allowing them to connect to several different services know at runtime.

It looks like right now there are only two options:

  1. Change the address, save it to a config file, restart the whole app,
  2. Don't use the provided client factory

How unfortunate 😢 Consider this my +1 to ".. a lot of community interest in this feature."

mindonwarp avatar Feb 19 '24 20:02 mindonwarp