-
Notifications
You must be signed in to change notification settings - Fork 138
rfq+server: properly configure gRPC keep alive settings for client+server #1834
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ import ( | |
"google.golang.org/grpc" | ||
"google.golang.org/grpc/credentials" | ||
"google.golang.org/grpc/credentials/insecure" | ||
"google.golang.org/grpc/keepalive" | ||
) | ||
|
||
// PriceQueryIntent is an enum that represents the intent of a price rate | ||
|
@@ -196,6 +197,21 @@ func serverDialOpts() ([]grpc.DialOption, error) { | |
transportCredentials := credentials.NewTLS(&tlsConfig) | ||
opts = append(opts, grpc.WithTransportCredentials(transportCredentials)) | ||
|
||
// Configure client-side keepalive parameters. These settings ensure | ||
// the client actively probes the connection health and prevents idle | ||
// connections from being silently closed by intermediaries or the | ||
// server. | ||
opts = append(opts, grpc.WithKeepaliveParams(keepalive.ClientParameters{ | ||
// Ping server after 30 seconds of inactivity. | ||
Time: 30 * time.Second, | ||
// Wait 20 seconds for ping response. | ||
Timeout: 20 * time.Second, | ||
// Permit keepalive pings even when there are no active | ||
// streams. This is critical for long-lived connections with | ||
// infrequent RFQ requests. | ||
PermitWithoutStream: true, | ||
})) | ||
|
||
return opts, nil | ||
} | ||
|
||
|
@@ -209,6 +225,21 @@ func insecureServerDialOpts() ([]grpc.DialOption, error) { | |
insecure.NewCredentials(), | ||
)) | ||
|
||
// Configure client-side keepalive parameters. These settings ensure | ||
// the client actively probes the connection health and prevents idle | ||
// connections from being silently closed by intermediaries or the | ||
// server. | ||
opts = append(opts, grpc.WithKeepaliveParams(keepalive.ClientParameters{ | ||
// Ping server after 30 seconds of inactivity. | ||
Time: 30 * time.Second, | ||
// Wait 20 seconds for ping response. | ||
Timeout: 20 * time.Second, | ||
// Permit keepalive pings even when there are no active | ||
// streams. This is critical for long-lived connections with | ||
// infrequent RFQ requests. | ||
PermitWithoutStream: true, | ||
})) | ||
Comment on lines
+228
to
+241
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block of code for configuring keep-alive parameters is identical to the one in For example, you could define: var clientKeepaliveDialOption = grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 30 * time.Second,
Timeout: 20 * time.Second,
PermitWithoutStream: true,
}) And then use it in both opts = append(opts, clientKeepaliveDialOption) This would make the code cleaner and easier to modify in the future. |
||
|
||
return opts, nil | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -370,11 +370,34 @@ func (s *Server) RunUntilShutdown(mainErrChan <-chan error) error { | |
serverOpts = append(serverOpts, rpcServerOpts...) | ||
serverOpts = append(serverOpts, ServerMaxMsgReceiveSize) | ||
|
||
keepAliveParams := keepalive.ServerParameters{ | ||
MaxConnectionIdle: time.Minute * 2, | ||
} | ||
|
||
serverOpts = append(serverOpts, grpc.KeepaliveParams(keepAliveParams)) | ||
// Configure server-side keepalive parameters. These settings allow the | ||
// server to actively probe the connection health and ensure connections | ||
// stay alive during idle periods. | ||
serverKeepalive := keepalive.ServerParameters{ | ||
// Ping client after 1 minute of inactivity. | ||
Time: time.Minute, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't it redundant to also have the server pinging the client? Why not just have it be the responsibility of the client There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This mirrors what lnd does,and we havne't had any issues with it. I view it as defense in depth. Can you think of a reason where the server also pinging will somehow disrupt the connection? |
||
// Wait 20 seconds for ping response. | ||
Timeout: 20 * time.Second, | ||
// Allow connections to remain idle for extended periods. This | ||
// is particularly important for RFQ operations where price | ||
// oracle connections may be idle for long periods. | ||
MaxConnectionIdle: time.Hour * 24, | ||
} | ||
|
||
// Configure client enforcement policy. This allows clients to send | ||
// keepalive pings even when there are no active streams, which is | ||
// crucial for long-lived connections with infrequent activity. | ||
clientKeepalive := keepalive.EnforcementPolicy{ | ||
// Minimum time between client pings. | ||
MinTime: 5 * time.Second, | ||
// Allow pings without active RPCs. | ||
PermitWithoutStream: true, | ||
} | ||
|
||
serverOpts = append( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This server is the tapd rpcserver. The oracle server is actually not implemented here so this has been misplaced. We could add it to the reference implementation in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is misplaced. The intent is that we resolve this on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can add it to the example oracle as well. |
||
serverOpts, grpc.KeepaliveParams(serverKeepalive), | ||
grpc.KeepaliveEnforcementPolicy(clientKeepalive), | ||
) | ||
|
||
grpcServer := grpc.NewServer(serverOpts...) | ||
defer grpcServer.Stop() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Do we want this to be a pure copy-paste of the opts on lines 200-214? Can't we reuse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, let's extract some consts or the whole configuration and re-use it