Skip to content

Commit 525a57e

Browse files
feat: setted keep alive settings
1 parent 867065c commit 525a57e

File tree

5 files changed

+78
-16
lines changed

5 files changed

+78
-16
lines changed

src/Ydb.Sdk/src/Ado/YdbConnectionStringBuilder.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,30 @@ public string? RootCertificate
137137

138138
private string? _rootCertificate;
139139

140+
public int KeepAlivePingDelay
141+
{
142+
get => _keepAlivePingDelay;
143+
set
144+
{
145+
_keepAlivePingDelay = value;
146+
SaveValue(nameof(KeepAlivePingDelay), value);
147+
}
148+
}
149+
150+
private int _keepAlivePingDelay = SocketHttpHandlerDefaults.DefaultKeepAlivePingSeconds;
151+
152+
public int KeepAlivePingTimeout
153+
{
154+
get => _keepAlivePingTimeout;
155+
set
156+
{
157+
_keepAlivePingTimeout = value;
158+
SaveValue(nameof(KeepAlivePingTimeout), value);
159+
}
160+
}
161+
162+
private int _keepAlivePingTimeout = SocketHttpHandlerDefaults.DefaultKeepAlivePingTimeoutSeconds;
163+
140164
public ILoggerFactory? LoggerFactory { get; init; }
141165

142166
public ICredentialsProvider? CredentialsProvider { get; init; }
@@ -193,7 +217,11 @@ internal Task<Driver> BuildDriver()
193217
credentials: credentialsProvider,
194218
customServerCertificate: cert,
195219
customServerCertificates: ServerCertificates
196-
), LoggerFactory);
220+
)
221+
{
222+
KeepAlivePingDelay = TimeSpan.FromSeconds(KeepAlivePingDelay),
223+
KeepAlivePingTimeout = TimeSpan.FromSeconds(KeepAlivePingTimeout)
224+
}, LoggerFactory);
197225
}
198226

199227
public override void Clear()
@@ -265,6 +293,12 @@ static YdbConnectionOption()
265293
new YdbConnectionOption<string>(StringExtractor,
266294
(builder, rootCertificate) => builder.RootCertificate = rootCertificate),
267295
"RootCertificate", "Root Certificate");
296+
AddOption(new YdbConnectionOption<int>(IntExtractor,
297+
(builder, keepAlivePingDelay) => builder.KeepAlivePingDelay = keepAlivePingDelay),
298+
"KeepAlivePingDelay", "Keep Alive Ping Delay");
299+
AddOption(new YdbConnectionOption<int>(IntExtractor,
300+
(builder, keepAlivePingTimeout) => builder.KeepAlivePingTimeout = keepAlivePingTimeout),
301+
"KeepAlivePingTimeout", "Keep Alive Ping Timeout");
268302
}
269303

270304
private static void AddOption(YdbConnectionOption option, params string[] keys)

src/Ydb.Sdk/src/DriverConfig.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ public class DriverConfig
99
public string Database { get; }
1010
public ICredentialsProvider Credentials { get; }
1111

12+
public TimeSpan KeepAlivePingDelay { get; set; } =
13+
TimeSpan.FromSeconds(SocketHttpHandlerDefaults.DefaultKeepAlivePingSeconds);
14+
15+
public TimeSpan KeepAlivePingTimeout { get; set; } =
16+
TimeSpan.FromSeconds(SocketHttpHandlerDefaults.DefaultKeepAlivePingTimeoutSeconds);
17+
1218
internal X509Certificate2Collection CustomServerCertificates { get; } = new();
1319
internal TimeSpan EndpointDiscoveryInterval = TimeSpan.FromMinutes(1);
1420
internal TimeSpan EndpointDiscoveryTimeout = TimeSpan.FromSeconds(10);

src/Ydb.Sdk/src/Pool/ChannelPool.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,17 @@ public interface IChannelFactory<out T> where T : ChannelBase, IDisposable
7575

7676
internal class GrpcChannelFactory : IChannelFactory<GrpcChannel>
7777
{
78-
private const int KeepAlivePingDelaySeconds = 10;
79-
8078
private readonly ILoggerFactory _loggerFactory;
8179
private readonly ILogger<GrpcChannelFactory> _logger;
82-
private readonly X509Certificate2Collection _x509Certificate2Collection;
80+
private readonly DriverConfig _config;
81+
82+
private X509Certificate2Collection ServerCertificates => _config.CustomServerCertificates;
8383

8484
internal GrpcChannelFactory(ILoggerFactory loggerFactory, DriverConfig config)
8585
{
8686
_loggerFactory = loggerFactory;
8787
_logger = loggerFactory.CreateLogger<GrpcChannelFactory>();
88-
_x509Certificate2Collection = config.CustomServerCertificates;
88+
_config = config;
8989
}
9090

9191
public GrpcChannel CreateChannel(string endpoint)
@@ -94,21 +94,24 @@ public GrpcChannel CreateChannel(string endpoint)
9494

9595
var channelOptions = new GrpcChannelOptions
9696
{
97-
LoggerFactory = _loggerFactory
97+
LoggerFactory = _loggerFactory,
98+
DisposeHttpClient = true
9899
};
99100

100101
var httpHandler = new SocketsHttpHandler
101102
{
102-
KeepAlivePingDelay = TimeSpan.FromSeconds(KeepAlivePingDelaySeconds)
103+
// https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md
104+
KeepAlivePingDelay = _config.KeepAlivePingDelay,
105+
KeepAlivePingTimeout = _config.KeepAlivePingTimeout,
106+
KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always
103107
};
104108

105109
// https://github.com/grpc/grpc-dotnet/issues/2312#issuecomment-1790661801
106110
httpHandler.Properties["__GrpcLoadBalancingDisabled"] = true;
107111

108112
channelOptions.HttpHandler = httpHandler;
109-
channelOptions.DisposeHttpClient = true;
110113

111-
if (_x509Certificate2Collection.Count == 0)
114+
if (ServerCertificates.Count == 0)
112115
{
113116
return GrpcChannel.ForAddress(endpoint, channelOptions);
114117
}
@@ -129,11 +132,11 @@ public GrpcChannel CreateChannel(string endpoint)
129132
try
130133
{
131134
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
132-
chain.ChainPolicy.ExtraStore.AddRange(_x509Certificate2Collection);
135+
chain.ChainPolicy.ExtraStore.AddRange(ServerCertificates);
133136

134-
return chain.Build(new X509Certificate2(certificate)) && chain.ChainElements.Any(chainElement =>
135-
_x509Certificate2Collection.Any(trustedCert =>
136-
chainElement.Certificate.Thumbprint == trustedCert.Thumbprint));
137+
return chain.Build(new X509Certificate2(certificate)) &&
138+
chain.ChainElements.Any(chainElement => ServerCertificates.Any(trustedCert =>
139+
chainElement.Certificate.Thumbprint == trustedCert.Thumbprint));
137140
}
138141
catch (Exception e)
139142
{
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace Ydb.Sdk;
2+
3+
internal static class SocketHttpHandlerDefaults
4+
{
5+
/// <summary>
6+
/// Default interval (in seconds) for sending keep-alive ping messages.
7+
/// </summary>
8+
internal const int DefaultKeepAlivePingSeconds = 10;
9+
10+
/// <summary>
11+
/// Default timeout (in seconds) for receiving a response to a keep-alive ping.
12+
/// </summary>
13+
internal const int DefaultKeepAlivePingTimeoutSeconds = 10;
14+
}

src/Ydb.Sdk/tests/Ado/YdbConnectionStringBuilderTests.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public void InitDefaultValues_WhenEmptyConstructorInvoke_ReturnDefaultConnection
1616
Assert.Equal(100, connectionString.MaxSessionPool);
1717
Assert.Null(connectionString.User);
1818
Assert.Null(connectionString.Password);
19+
Assert.Equal(10, connectionString.KeepAlivePingDelay);
20+
Assert.Equal(10, connectionString.KeepAlivePingTimeout);
1921
Assert.Equal("", connectionString.ConnectionString);
2022
}
2123

@@ -33,16 +35,19 @@ public void InitConnectionStringBuilder_WhenUnexpectedKey_ThrowException()
3335
public void InitConnectionStringBuilder_WhenExpectedKeys_ReturnUpdatedConnectionString()
3436
{
3537
var connectionString =
36-
new YdbConnectionStringBuilder("Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=true");
38+
new YdbConnectionStringBuilder("Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=true;" +
39+
"KeepAlivePingDelay=30;KeepAlivePingTimeout=60");
3740

3841
Assert.Equal(2135, connectionString.Port);
3942
Assert.Equal("server", connectionString.Host);
4043
Assert.Equal("/my/path", connectionString.Database);
4144
Assert.Equal(100, connectionString.MaxSessionPool);
4245
Assert.Equal("Kirill", connectionString.User);
46+
Assert.Equal(30, connectionString.KeepAlivePingDelay);
47+
Assert.Equal(60, connectionString.KeepAlivePingTimeout);
4348
Assert.Null(connectionString.Password);
44-
Assert.Equal("Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=True",
45-
connectionString.ConnectionString);
49+
Assert.Equal("Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=True;" +
50+
"KeepAlivePingDelay=30;KeepAlivePingTimeout=60", connectionString.ConnectionString);
4651
}
4752

4853
[Fact]

0 commit comments

Comments
 (0)