Skip to content

Commit bdc60ea

Browse files
committed
Fix IOException when Cancelling the monitor stream.
Added a wait to the MonitorEventsAsync_Succeeds test to have some progress messages.
1 parent 8e3cf4f commit bdc60ea

File tree

2 files changed

+21
-26
lines changed

2 files changed

+21
-26
lines changed

src/Docker.DotNet/Endpoints/StreamUtil.cs

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
using Newtonsoft.Json;
12
using System;
23
using System.IO;
34
using System.Net.Http;
45
using System.Text;
56
using System.Threading;
67
using System.Threading.Tasks;
7-
using Newtonsoft.Json;
88

99
namespace Docker.DotNet.Models
1010
{
@@ -17,15 +17,12 @@ internal static async Task MonitorStreamAsync(Task<Stream> streamTask, DockerCli
1717
using (var stream = await streamTask)
1818
{
1919
// ReadLineAsync must be cancelled by closing the whole stream.
20-
using (cancel.Register(() => stream.Dispose()))
20+
using (var reader = new StreamReader(stream, new UTF8Encoding(false)))
2121
{
22-
using (var reader = new StreamReader(stream, new UTF8Encoding(false)))
22+
string line;
23+
while ((line = await reader.ReadLineAsync()) != null && !cancel.IsCancellationRequested)
2324
{
24-
string line;
25-
while ((line = await reader.ReadLineAsync()) != null)
26-
{
27-
progress.Report(line);
28-
}
25+
progress.Report(line);
2926
}
3027
}
3128
}
@@ -49,32 +46,29 @@ internal static async Task MonitorResponseForMessagesAsync<T>(Task<HttpResponseM
4946
{
5047
using (var response = await responseTask)
5148
{
52-
await client.HandleIfErrorResponseAsync(response.StatusCode, response);
53-
5449
using (var stream = await response.Content.ReadAsStreamAsync())
5550
{
5651
// ReadLineAsync must be cancelled by closing the whole stream.
57-
using (cancel.Register(() => stream.Dispose()))
52+
using (var reader = new StreamReader(stream, new UTF8Encoding(false)))
5853
{
59-
using (var reader = new StreamReader(stream, new UTF8Encoding(false)))
54+
string line;
55+
try
6056
{
61-
string line;
62-
try
57+
while ((line = await reader.ReadLineAsync()) != null && !cancel.IsCancellationRequested)
6358
{
64-
while ((line = await reader.ReadLineAsync()) != null)
65-
{
66-
var prog = client.JsonSerializer.DeserializeObject<T>(line);
67-
if (prog == null) continue;
59+
await client.HandleIfErrorResponseAsync(response.StatusCode, response);
6860

69-
progress.Report(prog);
70-
}
71-
}
72-
catch (ObjectDisposedException)
73-
{
74-
// The subsequent call to reader.ReadLineAsync() after cancellation
75-
// will fail because we disposed the stream. Just ignore here.
61+
var prog = client.JsonSerializer.DeserializeObject<T>(line);
62+
if (prog == null) continue;
63+
64+
progress.Report(prog);
7665
}
7766
}
67+
catch (ObjectDisposedException)
68+
{
69+
// The subsequent call to reader.ReadLineAsync() after cancellation
70+
// will fail because we disposed the stream. Just ignore here.
71+
}
7872
}
7973
}
8074
}

test/Docker.DotNet.Tests/ISystemOperations.Tests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,11 @@ public async Task MonitorEventsAsync_Succeeds()
111111

112112
await _client.Images.CreateImageAsync(new ImagesCreateParameters { FromImage = "hello-world" }, null, progressJSONMessage);
113113

114-
var task = Task.Run(() => _client.System.MonitorEventsAsync(new ContainerEventsParameters(), progressMessage, cts.Token));
114+
var task = _client.System.MonitorEventsAsync(new ContainerEventsParameters(), progressMessage, cts.Token);
115115

116116
await _client.Images.TagImageAsync(repository, new ImageTagParameters { RepositoryName = repository, Tag = newTag });
117117

118+
Thread.Sleep(500); // Let's wait some time before cancelling the monitor stream to make sure we got some progress back.
118119
cts.Cancel();
119120

120121
bool taskIsCancelled = false;

0 commit comments

Comments
 (0)