httpclient to support different timeout for watch and regular api (#725)

* api for httpclient timeout

* testcases for global timeout

* update timeout to honor token

* generated files
This commit is contained in:
Boshi Lian
2021-10-11 12:55:02 -07:00
committed by GitHub
parent 78387dc44f
commit bc11d3aec2
5 changed files with 3435 additions and 2 deletions

View File

@@ -319,6 +319,16 @@ namespace k8s
Dictionary<string, List<string>> customHeaders = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(HttpClientTimeout);
{{#IfParamCotains operation "watch"}}
if (watch == true)
{
cts.CancelAfter(Timeout.InfiniteTimeSpan);
}
{{/IfParamCotains operation "watch"}}
cancellationToken = cts.Token;
{{#operation.parameters}}
{{#isRequired}}
if ({{GetDotNetName name}} == null)

View File

@@ -8,6 +8,7 @@ using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using k8s.Exceptions;
using k8s.Models;
using Microsoft.Rest;
@@ -16,6 +17,13 @@ namespace k8s
{
public partial class Kubernetes
{
/// <summary>
/// Timeout of REST calls to Kubernetes server
/// Does not apply to watch related api
/// </summary>
/// <value>timeout</value>
public TimeSpan HttpClientTimeout { get; set; } = TimeSpan.FromSeconds(100);
/// <summary>
/// Initializes a new instance of the <see cref="Kubernetes" /> class.
/// </summary>
@@ -69,6 +77,7 @@ namespace k8s
SkipTlsVerify = config.SkipTlsVerify;
CreateHttpClient(handlers, config);
InitializeFromConfig(config);
HttpClientTimeout = config.HttpClientTimeout;
}
private void ValidateConfig(KubernetesClientConfiguration config)
@@ -247,7 +256,10 @@ namespace k8s
}
}
HttpClient = new HttpClient(FirstMessageHandler, false);
HttpClient = new HttpClient(FirstMessageHandler, false)
{
Timeout = Timeout.InfiniteTimeSpan,
};
}
/// <summary>

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
@@ -79,8 +80,25 @@ namespace k8s
/// <value>The access token.</value>
public string AccessToken { get; set; }
/// <summary>
/// Gets or sets the TokenProvider for authentication.
/// </summary>
/// <value>The access token.</value>
public ITokenProvider TokenProvider { get; set; }
/// <summary>
/// Set true to enable tcp keep alive
/// You have to set https://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html as well
/// </summary>
/// <value>true or false</value>
public bool TcpKeepAlive { get; set; } = true;
/// <summary>
/// Timeout of REST calls to Kubernetes server
/// Does not apply to watch related api
/// </summary>
/// <value>timeout</value>
public TimeSpan HttpClientTimeout { get; set; } = TimeSpan.FromSeconds(100);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -552,9 +552,42 @@ namespace k8s.Tests
}
}
[Fact]
public async Task EnsureTimeoutWorks()
{
using var server = new MockKubeApiServer(testOutput, async httpContext =>
{
await Task.Delay(TimeSpan.FromSeconds(120)).ConfigureAwait(false); // The default timeout is 100 seconds
await WriteStreamLine(httpContext, MockKubeApiServer.MockPodResponse).ConfigureAwait(false);
return false;
});
[Fact(Skip = "https://github.com/kubernetes-client/csharp/issues/165")]
// raw timeout
await Assert.ThrowsAsync<TaskCanceledException>(async () =>
{
var client = new Kubernetes(new KubernetesClientConfiguration
{
Host = server.Uri.ToString(),
HttpClientTimeout = TimeSpan.FromSeconds(5),
});
await client.ListNamespacedPodWithHttpMessagesAsync("default").ConfigureAwait(false);
}).ConfigureAwait(false);
// cts
await Assert.ThrowsAsync<TaskCanceledException>(async () =>
{
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(5));
var client = new Kubernetes(new KubernetesClientConfiguration
{
Host = server.Uri.ToString(),
});
await client.ListNamespacedPodWithHttpMessagesAsync("default", cancellationToken: cts.Token).ConfigureAwait(false);
}).ConfigureAwait(false);
}
[Fact]
public async Task DirectWatchEventsWithTimeout()
{
var eventsReceived = new AsyncCountdownEvent(4);