Skip to content

Commit 0f9e00c

Browse files
committed
Ensure that awaits do not continue on the captured context.
1 parent c8de0ca commit 0f9e00c

File tree

8 files changed

+27
-25
lines changed

8 files changed

+27
-25
lines changed

src/KubernetesClient/Kubernetes.WebSocket.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ public partial class Kubernetes
273273
{
274274
// Copy the default (credential-related) request headers from the HttpClient to the WebSocket
275275
HttpRequestMessage message = new HttpRequestMessage();
276-
await this.Credentials.ProcessHttpRequestAsync(message, cancellationToken);
276+
await this.Credentials.ProcessHttpRequestAsync(message, cancellationToken).ConfigureAwait(false);
277277

278278
foreach (var _header in message.Headers)
279279
{

src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFil
100100
throw new NullReferenceException(nameof(kubeconfig));
101101
}
102102

103-
var k8SConfig = await LoadKubeConfigAsync(kubeconfig, useRelativePaths);
103+
var k8SConfig = await LoadKubeConfigAsync(kubeconfig, useRelativePaths).ConfigureAwait(false);
104104
var k8SConfiguration = GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
105105

106106
return k8SConfiguration;
@@ -139,7 +139,7 @@ public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFil
139139

140140
kubeconfig.Position = 0;
141141

142-
var k8SConfig = await Yaml.LoadFromStreamAsync<K8SConfiguration>(kubeconfig);
142+
var k8SConfig = await Yaml.LoadFromStreamAsync<K8SConfiguration>(kubeconfig).ConfigureAwait(false);
143143
var k8SConfiguration = GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
144144

145145
return k8SConfiguration;
@@ -479,7 +479,7 @@ public static async Task<K8SConfiguration> LoadKubeConfigAsync(string kubeconfig
479479
{
480480
var fileInfo = new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation);
481481

482-
return await LoadKubeConfigAsync(fileInfo, useRelativePaths);
482+
return await LoadKubeConfigAsync(fileInfo, useRelativePaths).ConfigureAwait(false);
483483
}
484484

485485
/// <summary>
@@ -510,7 +510,7 @@ public static async Task<K8SConfiguration> LoadKubeConfigAsync(FileInfo kubeconf
510510

511511
using (var stream = kubeconfig.OpenRead())
512512
{
513-
var config = await Yaml.LoadFromStreamAsync<K8SConfiguration>(stream);
513+
var config = await Yaml.LoadFromStreamAsync<K8SConfiguration>(stream).ConfigureAwait(false);
514514

515515
if (useRelativePaths)
516516
{
@@ -540,7 +540,7 @@ public static K8SConfiguration LoadKubeConfig(FileInfo kubeconfig, bool useRelat
540540
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
541541
public static async Task<K8SConfiguration> LoadKubeConfigAsync(Stream kubeconfigStream)
542542
{
543-
return await Yaml.LoadFromStreamAsync<K8SConfiguration>(kubeconfigStream);
543+
return await Yaml.LoadFromStreamAsync<K8SConfiguration>(kubeconfigStream).ConfigureAwait(false);
544544
}
545545

546546
/// <summary>

src/KubernetesClient/StreamDemuxer.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public StreamDemuxer(WebSocket webSocket, StreamType streamType = StreamType.Rem
5757
/// </summary>
5858
public void Start()
5959
{
60-
this.runLoop = this.RunLoop(this.cts.Token);
60+
this.runLoop = Task.Run(() => this.RunLoop(this.cts.Token));
6161
}
6262

6363
/// <inheritdoc/>
@@ -193,9 +193,6 @@ public Stream GetStream(byte? inputIndex, byte? outputIndex)
193193

194194
protected async Task RunLoop(CancellationToken cancellationToken)
195195
{
196-
// This is a background task. Immediately yield to the caller.
197-
await Task.Yield();
198-
199196
// Get a 1KB buffer
200197
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024 * 1024);
201198
// This maps remembers bytes skipped for each stream.

src/KubernetesClient/Watcher.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public Watcher(Func<Task<StreamReader>> streamReaderCreator, Action<WatchEventTy
5757
OnClosed += onClosed;
5858

5959
_cts = new CancellationTokenSource();
60-
_watcherLoop = this.WatcherLoop(_cts.Token);
60+
_watcherLoop = Task.Run(() => this.WatcherLoop(_cts.Token));
6161
}
6262

6363
/// <inheritdoc/>
@@ -91,14 +91,11 @@ public class WatchEvent
9191

9292
private async Task WatcherLoop(CancellationToken cancellationToken)
9393
{
94-
// Make sure we run async
95-
await Task.Yield();
96-
9794
try
9895
{
9996
Watching = true;
10097
string line;
101-
_streamReader = await _streamReaderCreator();
98+
_streamReader = await _streamReaderCreator().ConfigureAwait(false);
10299

103100
// ReadLineAsync will return null when we've reached the end of the stream.
104101
while ((line = await _streamReader.ReadLineAsync().ConfigureAwait(false)) != null)
@@ -164,7 +161,7 @@ public static Watcher<T> Watch<T, L>(this Task<HttpOperationResponse<L>> respons
164161
Action onClosed = null)
165162
{
166163
return new Watcher<T>(async () => {
167-
var response = await responseTask;
164+
var response = await responseTask.ConfigureAwait(false);
168165

169166
if (!(response.Response.Content is WatcherDelegatingHandler.LineSeparatedHttpContent content))
170167
{

src/KubernetesClient/WatcherDelegatingHandler.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal class WatcherDelegatingHandler : DelegatingHandler
1919
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
2020
CancellationToken cancellationToken)
2121
{
22-
var originResponse = await base.SendAsync(request, cancellationToken);
22+
var originResponse = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
2323

2424
if (originResponse.IsSuccessStatusCode)
2525
{
@@ -47,18 +47,18 @@ public LineSeparatedHttpContent(HttpContent originContent)
4747

4848
protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
4949
{
50-
_originStream = await _originContent.ReadAsStreamAsync();
50+
_originStream = await _originContent.ReadAsStreamAsync().ConfigureAwait(false);
5151

5252
StreamReader = new PeekableStreamReader(_originStream);
5353

54-
var firstLine = await StreamReader.PeekLineAsync();
54+
var firstLine = await StreamReader.PeekLineAsync().ConfigureAwait(false);
5555

5656
var writer = new StreamWriter(stream);
5757

5858
// using (writer) // leave open
5959
{
60-
await writer.WriteAsync(firstLine);
61-
await writer.FlushAsync();
60+
await writer.WriteAsync(firstLine).ConfigureAwait(false);
61+
await writer.FlushAsync().ConfigureAwait(false);
6262
}
6363
}
6464

@@ -94,7 +94,7 @@ public override Task<string> ReadLineAsync()
9494
}
9595
public async Task<string> PeekLineAsync()
9696
{
97-
var line = await ReadLineAsync();
97+
var line = await ReadLineAsync().ConfigureAwait(false);
9898
_buffer.Enqueue(line);
9999
return line;
100100
}

src/KubernetesClient/Yaml.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class Yaml {
2929
/// </param>
3030
public static async Task<List<object>> LoadAllFromStreamAsync(Stream stream, Dictionary<String, Type> typeMap) {
3131
var reader = new StreamReader(stream);
32-
var content = await reader.ReadToEndAsync();
32+
var content = await reader.ReadToEndAsync().ConfigureAwait(false);
3333
return LoadAllFromString(content, typeMap);
3434
}
3535

@@ -95,13 +95,13 @@ public static List<object> LoadAllFromString(String content, Dictionary<String,
9595

9696
public static async Task<T> LoadFromStreamAsync<T>(Stream stream) {
9797
var reader = new StreamReader(stream);
98-
var content = await reader.ReadToEndAsync();
98+
var content = await reader.ReadToEndAsync().ConfigureAwait(false);
9999
return LoadFromString<T>(content);
100100
}
101101

102102
public static async Task<T> LoadFromFileAsync<T> (string file) {
103103
using (FileStream fs = File.OpenRead(file)) {
104-
return await LoadFromStreamAsync<T>(fs);
104+
return await LoadFromStreamAsync<T>(fs).ConfigureAwait(false);
105105
}
106106
}
107107

tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
3434
<PackageReference Include="xunit" Version="2.4.1" />
3535
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
36+
<PackageReference Include="Xunit.StaFact" Version="0.3.18" />
3637
<PackageReference Include="Moq" Version="4.13.1" />
3738

3839
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />

tests/KubernetesClient.Tests/KubernetesClientConfigurationTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,13 @@ public void LoadKubeConfigStream()
383383
AssertConfigEqual(expectedCfg, cfg);
384384
}
385385

386+
[UIFact]
387+
public void BuildConfigFromConfigFileInfoOnNonDefaultSynchronizationContext()
388+
{
389+
var fi = new FileInfo("assets/kubeconfig.yml");
390+
KubernetesClientConfiguration.BuildConfigFromConfigFile(fi, "federal-context", useRelativePaths: false);
391+
}
392+
386393
private void AssertConfigEqual(K8SConfiguration expected, K8SConfiguration actual)
387394
{
388395
Assert.Equal(expected.ApiVersion, actual.ApiVersion);

0 commit comments

Comments
 (0)