Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to determine when underlying connection has been made #643

Closed
smudge202 opened this issue Nov 6, 2019 · 5 comments
Closed

Ability to determine when underlying connection has been made #643

smudge202 opened this issue Nov 6, 2019 · 5 comments
Labels
enhancement New feature or request
Milestone

Comments

@smudge202
Copy link

smudge202 commented Nov 6, 2019

Is your feature request related to a problem? Please describe.

I need the ability to determine when a connection is made. Specifically with a bi-directional stream call, but I believe all calls are effected.

This was discussed briefly on twitter.

Describe the solution you'd like

When https://github.com/dotnet/corefx/issues/35404 is complete, it should be possible to expose when the connection is established. I proposed doing so by allowing callers to await an Async variant of the GRPC generated client call. Alternatively, allowing a consumer to subscribe to a Connected or StatusChanged event on the generated Client might be preferable if the former proposal introduces inconsistent behaviour between sync/async calls.

Describe alternatives you've considered

Looking at the HttpClientCallInvoker and it's call through to GrpcCall I was hoping there was an alternative to voiding the RunCall Task, but HttpClient doesn't express when connections are established (yet).

@smudge202 smudge202 added the enhancement New feature or request label Nov 6, 2019
@JamesNK
Copy link
Member

JamesNK commented Nov 6, 2019

I need the ability to determine when a connection is made. Specifically with a bi-directional stream call, but I believe all calls are effected.

What problem are you solving? It is useful to us to understand why something is needed and how it would be used when evaluate implementing it.

@smudge202
Copy link
Author

smudge202 commented Nov 6, 2019

What problem are you solving?

Yeh, I left it abstract as the problem I'm trying to solve is a little involved and I didn't want to muddy the issue too much. I suspect there's much simpler use cases to examine, but, since you ask...

I have an agent that sits deep behind some firewalls, and an api which we'll assume is in the DMZ for brevity's sake. We don't want to punch holes from DMZ to agent (rather any holes be the other way around). So on startup the api uses an intermediary to signal the agent (said intermediary respecting the outward only f/w rules). The agent (client) then establishes a gRPC connection to the api (server), but with an inversed bi-directional stream that looks as follows:

service AgentConnectionService {
	// request & response intentionally inverted
	// "client" connects allowing "server" to make requests
	// (this gets around outbound only firewall constraints)
	rpc Connect(stream Response) returns (stream Request);
}

There is no guarantee that any requests are pending at the point the connection is established / the call is first placed. I can detect when the client connects to the server on the server side because it'll hit the service override, i.e.

public override async Task Connect(IAsyncStreamReader<Response> requestStream, IServerStreamWriter<Request> responseStream, ServerCallContext context)
{
    // if we get here, I know the client has connected
}

I can't however do the same on the client side, because the initial call will void the HttpClient Tasks

var httpClient = new HttpClient(handler);
var options = new GrpcChannelOptions { HttpClient = httpClient };
var channel = GrpcChannel.ForAddress(address, options);
var client = new AgentConnectionService.AgentConnectionServiceClient(channel);
var call = client.Connect();
// am I connected or not? No way of knowing until/unless a message is sent/received

I can attempt to work around this by having the server send a message immediately after a connection is established and/or having a ping/pong. The health of this aspect of the service is determined by the apis ability to ""respond"" (by sending a request in the above signature) to the agent, and I would like to monitor that health on both sides of the connection.

I appreciate there are probably some complexities around how some of the connections work, when they're actually available, etc, which may make this request unfeasible? Definitely appreciate any insights (or pointers to good material to read up on) if that's the case.

@jtattermusch
Copy link
Contributor

I think this basically boils down to #874?

@scalablecory
Copy link

This has been resolved via the API added here in .NET 5: dotnet/runtime#41949

@JamesNK JamesNK modified the milestones: 5.0, 6.0 Nov 11, 2020
@JamesNK JamesNK removed the blocked label Sep 2, 2021
@JamesNK
Copy link
Member

JamesNK commented Sep 2, 2021

Available now in preview releases together with load balancing

https://docs.microsoft.com/en-us/aspnet/core/grpc/loadbalancing?view=aspnetcore-5.0

@JamesNK JamesNK closed this as completed Sep 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants