-
Notifications
You must be signed in to change notification settings - Fork 380
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
David García Vives
committed
Mar 3, 2021
1 parent
0d13c41
commit f0336bf
Showing
12 changed files
with
1,367 additions
and
286 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,55 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net.Http; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Newtonsoft.Json; | ||
|
||
namespace Docker.DotNet.Models | ||
{ | ||
internal static class StreamUtil | ||
{ | ||
private static Newtonsoft.Json.JsonSerializer _serializer = new Newtonsoft.Json.JsonSerializer(); | ||
|
||
internal static async Task MonitorStreamAsync(Task<Stream> streamTask, DockerClient client, CancellationToken cancel, IProgress<string> progress) | ||
{ | ||
using (var stream = await streamTask) | ||
{ | ||
// ReadLineAsync must be cancelled by closing the whole stream. | ||
using (cancel.Register(() => stream.Dispose())) | ||
{ | ||
using (var reader = new StreamReader(stream, new UTF8Encoding(false))) | ||
{ | ||
string line; | ||
while ((line = await reader.ReadLineAsync()) != null) | ||
{ | ||
progress.Report(line); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
internal static async Task MonitorStreamForMessagesAsync<T>(Task<Stream> streamTask, DockerClient client, CancellationToken cancel, IProgress<T> progress) | ||
{ | ||
using (var stream = await streamTask) | ||
using (var reader = new StreamReader(stream, new UTF8Encoding(false))) | ||
using (var jsonReader = new JsonTextReader(reader) { SupportMultipleContent = true }) | ||
{ | ||
while (await jsonReader.ReadAsync().WithCancellation(cancel)) | ||
{ | ||
var ev = _serializer.Deserialize<T>(jsonReader); | ||
progress?.Report(ev); | ||
} | ||
} | ||
} | ||
|
||
internal static async Task MonitorResponseForMessagesAsync<T>(Task<HttpResponseMessage> responseTask, DockerClient client, CancellationToken cancel, IProgress<T> progress) | ||
{ | ||
using (var response = await responseTask) | ||
{ | ||
await client.HandleIfErrorResponseAsync(response.StatusCode, response); | ||
|
||
using (var stream = await response.Content.ReadAsStreamAsync()) | ||
{ | ||
// ReadLineAsync must be cancelled by closing the whole stream. | ||
using (cancel.Register(() => stream.Dispose())) | ||
{ | ||
using (var reader = new StreamReader(stream, new UTF8Encoding(false))) | ||
{ | ||
string line; | ||
try | ||
{ | ||
while ((line = await reader.ReadLineAsync()) != null) | ||
{ | ||
var prog = client.JsonSerializer.DeserializeObject<T>(line); | ||
if (prog == null) continue; | ||
|
||
progress.Report(prog); | ||
} | ||
} | ||
catch (ObjectDisposedException) | ||
{ | ||
// The subsequent call to reader.ReadLineAsync() after cancellation | ||
// will fail because we disposed the stream. Just ignore here. | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken) | ||
{ | ||
var tcs = new TaskCompletionSource<bool>(); | ||
using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs)) | ||
{ | ||
if (task != await Task.WhenAny(task, tcs.Task)) | ||
{ | ||
throw new OperationCanceledException(cancellationToken); | ||
} | ||
} | ||
|
||
return await task; | ||
} | ||
} | ||
} | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Net.Http; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Newtonsoft.Json; | ||
|
||
namespace Docker.DotNet.Models | ||
{ | ||
internal static class StreamUtil | ||
{ | ||
internal static async Task MonitorStreamAsync(Task<Stream> streamTask, DockerClient client, CancellationToken cancellationToken, IProgress<string> progress) | ||
{ | ||
var tcs = new TaskCompletionSource<string>(); | ||
|
||
using (var stream = await streamTask) | ||
using (var reader = new StreamReader(stream, new UTF8Encoding(false))) | ||
using (cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken))) | ||
{ | ||
string line; | ||
while ((line = await await Task.WhenAny(reader.ReadLineAsync(), tcs.Task)) != null) | ||
{ | ||
progress.Report(line); | ||
} | ||
} | ||
} | ||
|
||
internal static async Task MonitorStreamForMessagesAsync<T>(Task<Stream> streamTask, DockerClient client, CancellationToken cancellationToken, IProgress<T> progress) | ||
{ | ||
var tcs = new TaskCompletionSource<bool>(); | ||
|
||
using (var stream = await streamTask) | ||
using (var reader = new StreamReader(stream, new UTF8Encoding(false))) | ||
using (var jsonReader = new JsonTextReader(reader) { SupportMultipleContent = true }) | ||
using (cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken))) | ||
{ | ||
while (await await Task.WhenAny(jsonReader.ReadAsync(cancellationToken), tcs.Task)) | ||
{ | ||
var ev = await client.JsonSerializer.Deserialize<T>(jsonReader, cancellationToken); | ||
progress.Report(ev); | ||
} | ||
} | ||
} | ||
|
||
internal static async Task MonitorResponseForMessagesAsync<T>(Task<HttpResponseMessage> responseTask, DockerClient client, CancellationToken cancel, IProgress<T> progress) | ||
{ | ||
using (var response = await responseTask) | ||
{ | ||
await MonitorStreamForMessagesAsync<T>(response.Content.ReadAsStreamAsync(), client, cancel, progress); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.