Skip to content

Commit 0c4b970

Browse files
committed
Add grpc keep alive
Signed-off-by: Jonathan Collinge <[email protected]>
1 parent 6b49bed commit 0c4b970

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

src/Dapr.Workflow/DaprWorkflowClientBuilderFactory.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public void CreateClientBuilder(IServiceCollection services, Action<WorkflowRunt
6464
HttpClient = httpClient
6565
};
6666

67+
GrpcKeepAlive.Configure(options, channelOptions);
68+
6769
builder.UseGrpc(GrpcChannel.ForAddress(grpcEndpoint, channelOptions));
6870
builder.RegisterDirectly();
6971
});
@@ -90,6 +92,8 @@ public void CreateClientBuilder(IServiceCollection services, Action<WorkflowRunt
9092
HttpClient = httpClient
9193
};
9294

95+
GrpcKeepAlive.Configure(options, channelOptions);
96+
9397
builder.UseGrpc(GrpcChannel.ForAddress(grpcEndpoint, channelOptions));
9498
}
9599
else

src/Dapr.Workflow/GrpcKeepAlive.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Net.Http;
3+
using Grpc.Net.Client;
4+
5+
namespace Dapr.Workflow
6+
{
7+
internal static class GrpcKeepAlive
8+
{
9+
public static void Configure(WorkflowRuntimeOptions options, GrpcChannelOptions channelOptions)
10+
{
11+
// We check whether the environment variables are set to override
12+
// the options. The environment variables ensure consistency between
13+
// the different Dapr SDKs.
14+
string? enableKeepAlive = Environment.GetEnvironmentVariable("DAPR_ENABLE_KEEP_ALIVE");
15+
if (enableKeepAlive != null)
16+
{
17+
options.EnableKeepAlive = bool.Parse(enableKeepAlive);
18+
}
19+
string? keepAliveTime = Environment.GetEnvironmentVariable("DAPR_KEEP_ALIVE_TIME");
20+
if (keepAliveTime != null)
21+
{
22+
options.KeepAliveTime = TimeSpan.FromSeconds(int.Parse(keepAliveTime));
23+
}
24+
string? keepAliveTimeout = Environment.GetEnvironmentVariable("DAPR_KEEP_ALIVE_TIMEOUT");
25+
if (keepAliveTimeout != null)
26+
{
27+
options.KeepAliveTimeout = TimeSpan.FromSeconds(int.Parse(keepAliveTimeout));
28+
}
29+
string? keepAliveWithoutCalls = Environment.GetEnvironmentVariable("DAPR_KEEP_ALIVE_WITHOUT_CALLS");
30+
if (keepAliveWithoutCalls != null)
31+
{
32+
options.KeepAliveWithoutCalls = bool.Parse(keepAliveWithoutCalls);
33+
}
34+
if (!options.EnableKeepAlive)
35+
{
36+
return;
37+
}
38+
39+
if (channelOptions.HttpHandler is not SocketsHttpHandler socketsHandler)
40+
{
41+
socketsHandler = new SocketsHttpHandler();
42+
channelOptions.HttpHandler = socketsHandler;
43+
}
44+
45+
socketsHandler.KeepAlivePingDelay = options.KeepAliveTime;
46+
socketsHandler.KeepAlivePingTimeout = options.KeepAliveTimeout;
47+
#if NET8_0_OR_GREATER
48+
socketsHandler.KeepAlivePingPolicy = options.KeepAliveWithoutCalls
49+
? HttpKeepAlivePingPolicy.Always
50+
: HttpKeepAlivePingPolicy.WithActiveRequests;
51+
#endif
52+
}
53+
}
54+
}

src/Dapr.Workflow/WorkflowRuntimeOptions.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,26 @@ internal void AddWorkflowsAndActivitiesToRegistry(DurableTaskRegistry registry)
146146
}
147147
}
148148

149+
/// <summary>
150+
/// Enables gRPC keepalive pings on all connections.
151+
/// </summary>
152+
public bool EnableKeepAlive { get; set; } = false;
153+
154+
/// <summary>
155+
/// The delay between keepalive pings. Default is 60 seconds.
156+
/// </summary>
157+
public TimeSpan KeepAliveTime { get; set; } = TimeSpan.FromSeconds(60);
158+
159+
/// <summary>
160+
/// The timeout for keepalive pings. Default is 20 seconds.
161+
/// </summary>
162+
public TimeSpan KeepAliveTimeout { get; set; } = TimeSpan.FromSeconds(20);
163+
164+
/// <summary>
165+
/// Whether to send keepalive pings even with no active calls. Default is true.
166+
/// </summary>
167+
public bool KeepAliveWithoutCalls { get; set; } = true;
168+
149169
/// <summary>
150170
/// Helper class that provides a Durable Task orchestrator wrapper for a workflow.
151171
/// </summary>

0 commit comments

Comments
 (0)