diff --git a/src/KubernetesClient/Kubernetes.WebSocket.cs b/src/KubernetesClient/Kubernetes.WebSocket.cs index 0aa354e..9d336d5 100644 --- a/src/KubernetesClient/Kubernetes.WebSocket.cs +++ b/src/KubernetesClient/Kubernetes.WebSocket.cs @@ -273,7 +273,7 @@ namespace k8s { // Copy the default (credential-related) request headers from the HttpClient to the WebSocket HttpRequestMessage message = new HttpRequestMessage(); - await this.Credentials.ProcessHttpRequestAsync(message, cancellationToken); + await this.Credentials.ProcessHttpRequestAsync(message, cancellationToken).ConfigureAwait(false); foreach (var _header in message.Headers) { diff --git a/src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs b/src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs index e6ead20..0d3c66b 100644 --- a/src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs +++ b/src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs @@ -100,7 +100,7 @@ namespace k8s throw new NullReferenceException(nameof(kubeconfig)); } - var k8SConfig = await LoadKubeConfigAsync(kubeconfig, useRelativePaths); + var k8SConfig = await LoadKubeConfigAsync(kubeconfig, useRelativePaths).ConfigureAwait(false); var k8SConfiguration = GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig); return k8SConfiguration; @@ -139,7 +139,7 @@ namespace k8s kubeconfig.Position = 0; - var k8SConfig = await Yaml.LoadFromStreamAsync(kubeconfig); + var k8SConfig = await Yaml.LoadFromStreamAsync(kubeconfig).ConfigureAwait(false); var k8SConfiguration = GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig); return k8SConfiguration; @@ -486,7 +486,7 @@ namespace k8s { var fileInfo = new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation); - return await LoadKubeConfigAsync(fileInfo, useRelativePaths); + return await LoadKubeConfigAsync(fileInfo, useRelativePaths).ConfigureAwait(false); } /// @@ -517,7 +517,7 @@ namespace k8s using (var stream = kubeconfig.OpenRead()) { - var config = await Yaml.LoadFromStreamAsync(stream); + var config = await Yaml.LoadFromStreamAsync(stream).ConfigureAwait(false); if (useRelativePaths) { @@ -547,7 +547,7 @@ namespace k8s /// Instance of the class public static async Task LoadKubeConfigAsync(Stream kubeconfigStream) { - return await Yaml.LoadFromStreamAsync(kubeconfigStream); + return await Yaml.LoadFromStreamAsync(kubeconfigStream).ConfigureAwait(false); } /// diff --git a/src/KubernetesClient/StreamDemuxer.cs b/src/KubernetesClient/StreamDemuxer.cs index 4944046..e0687f1 100644 --- a/src/KubernetesClient/StreamDemuxer.cs +++ b/src/KubernetesClient/StreamDemuxer.cs @@ -57,7 +57,7 @@ namespace k8s /// public void Start() { - this.runLoop = this.RunLoop(this.cts.Token); + this.runLoop = Task.Run(async () => await this.RunLoop(this.cts.Token)); } /// @@ -193,9 +193,6 @@ namespace k8s protected async Task RunLoop(CancellationToken cancellationToken) { - // This is a background task. Immediately yield to the caller. - await Task.Yield(); - // Get a 1KB buffer byte[] buffer = ArrayPool.Shared.Rent(1024 * 1024); // This maps remembers bytes skipped for each stream. diff --git a/src/KubernetesClient/Watcher.cs b/src/KubernetesClient/Watcher.cs index e4db6f9..045c4b9 100644 --- a/src/KubernetesClient/Watcher.cs +++ b/src/KubernetesClient/Watcher.cs @@ -57,7 +57,7 @@ namespace k8s OnClosed += onClosed; _cts = new CancellationTokenSource(); - _watcherLoop = this.WatcherLoop(_cts.Token); + _watcherLoop = Task.Run(async () => await this.WatcherLoop(_cts.Token)); } /// @@ -91,14 +91,11 @@ namespace k8s private async Task WatcherLoop(CancellationToken cancellationToken) { - // Make sure we run async - await Task.Yield(); - try { Watching = true; string line; - _streamReader = await _streamReaderCreator(); + _streamReader = await _streamReaderCreator().ConfigureAwait(false); // ReadLineAsync will return null when we've reached the end of the stream. while ((line = await _streamReader.ReadLineAsync().ConfigureAwait(false)) != null) @@ -164,7 +161,7 @@ namespace k8s Action onClosed = null) { return new Watcher(async () => { - var response = await responseTask; + var response = await responseTask.ConfigureAwait(false); if (!(response.Response.Content is WatcherDelegatingHandler.LineSeparatedHttpContent content)) { diff --git a/src/KubernetesClient/WatcherDelegatingHandler.cs b/src/KubernetesClient/WatcherDelegatingHandler.cs index 401fe8b..9ecf2fa 100644 --- a/src/KubernetesClient/WatcherDelegatingHandler.cs +++ b/src/KubernetesClient/WatcherDelegatingHandler.cs @@ -19,7 +19,7 @@ namespace k8s protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - var originResponse = await base.SendAsync(request, cancellationToken); + var originResponse = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); if (originResponse.IsSuccessStatusCode) { @@ -47,18 +47,18 @@ namespace k8s protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context) { - _originStream = await _originContent.ReadAsStreamAsync(); + _originStream = await _originContent.ReadAsStreamAsync().ConfigureAwait(false); StreamReader = new PeekableStreamReader(_originStream); - var firstLine = await StreamReader.PeekLineAsync(); + var firstLine = await StreamReader.PeekLineAsync().ConfigureAwait(false); var writer = new StreamWriter(stream); // using (writer) // leave open { - await writer.WriteAsync(firstLine); - await writer.FlushAsync(); + await writer.WriteAsync(firstLine).ConfigureAwait(false); + await writer.FlushAsync().ConfigureAwait(false); } } @@ -94,7 +94,7 @@ namespace k8s } public async Task PeekLineAsync() { - var line = await ReadLineAsync(); + var line = await ReadLineAsync().ConfigureAwait(false); _buffer.Enqueue(line); return line; } diff --git a/src/KubernetesClient/Yaml.cs b/src/KubernetesClient/Yaml.cs index ad98e72..d51cc0d 100644 --- a/src/KubernetesClient/Yaml.cs +++ b/src/KubernetesClient/Yaml.cs @@ -29,7 +29,7 @@ namespace k8s /// public static async Task> LoadAllFromStreamAsync(Stream stream, Dictionary typeMap) { var reader = new StreamReader(stream); - var content = await reader.ReadToEndAsync(); + var content = await reader.ReadToEndAsync().ConfigureAwait(false); return LoadAllFromString(content, typeMap); } @@ -95,13 +95,13 @@ namespace k8s public static async Task LoadFromStreamAsync(Stream stream) { var reader = new StreamReader(stream); - var content = await reader.ReadToEndAsync(); + var content = await reader.ReadToEndAsync().ConfigureAwait(false); return LoadFromString(content); } public static async Task LoadFromFileAsync (string file) { using (FileStream fs = File.OpenRead(file)) { - return await LoadFromStreamAsync(fs); + return await LoadFromStreamAsync(fs).ConfigureAwait(false); } } diff --git a/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj b/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj index c9f5822..ac41d17 100755 --- a/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj +++ b/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj @@ -33,6 +33,7 @@ + diff --git a/tests/KubernetesClient.Tests/KubernetesClientConfigurationTests.cs b/tests/KubernetesClient.Tests/KubernetesClientConfigurationTests.cs index 564a96c..341a252 100755 --- a/tests/KubernetesClient.Tests/KubernetesClientConfigurationTests.cs +++ b/tests/KubernetesClient.Tests/KubernetesClientConfigurationTests.cs @@ -1,5 +1,6 @@ using System.IO; using System.Linq; +using System.Threading; using k8s.Exceptions; using k8s.KubeConfigModels; using Xunit; @@ -406,6 +407,17 @@ namespace k8s.Tests AssertConfigEqual(expectedCfg, cfg); } + /// + /// Ensures Kube config file can be loaded from within a non-default . + /// The use of ensures the test is run from within a UI-like . + /// + [UIFact] + public void BuildConfigFromConfigFileInfoOnNonDefaultSynchronizationContext() + { + var fi = new FileInfo("assets/kubeconfig.yml"); + KubernetesClientConfiguration.BuildConfigFromConfigFile(fi, "federal-context", useRelativePaths: false); + } + private void AssertConfigEqual(K8SConfiguration expected, K8SConfiguration actual) { Assert.Equal(expected.ApiVersion, actual.ApiVersion);