Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement proper handling of Docker Streams #147

Merged
merged 6 commits into from
Jan 19, 2017
Merged

Implement proper handling of Docker Streams #147

merged 6 commits into from
Jan 19, 2017

Conversation

galvesribeiro
Copy link
Member

@galvesribeiro galvesribeiro commented Jan 18, 2017

This PR implements #108

Read and notify properly Docker event Streams in:

  • Image Operations
  • Container Logs
  • Container Stats
  • MISC endpoint Monitor Event

This PR will be update with one commit for each part to make easier to review.

@msftclas
Copy link

Hi @galvesribeiro, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!

The agreement was validated by Microsoft and real humans are currently evaluating your PR.

TTYL, MSBOT;

@galvesribeiro galvesribeiro changed the title [WIP] Implement proper handling of Docker Streams Implement proper handling of Docker Streams Jan 18, 2017
@@ -238,7 +238,7 @@ public Task RemoveContainerAsync(string id, ContainerRemoveParameters parameters
return this._client.MakeRequestAsync(new[] { NoSuchContainerHandler }, HttpMethod.Delete, $"containers/{id}", queryParameters);
}

public Task<Stream> GetContainerLogsAsync(string id, ContainerLogsParameters parameters, CancellationToken cancellationToken)
public async Task GetContainerLogsAsync(string id, ContainerLogsParameters parameters, CancellationToken cancellationToken, IProgress<string> logReport = null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this. Leave the old method and add an [Obsolete] tag with reference to the new sig. Have this new method call the old one to get the stream and just do the while (can read) { report } part. Then we have no breaking changes but we do alert people to use the new method. And then in the next version of docker I will pull the [Obsolete] method and merge the logic to just the IProgress{T} variant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also how do you feel about just calling it IProgress<string> progress = null

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! Let me change that.

var line = await reader.ReadLineAsync();
if (logReport == null) continue;

logReport.Report(line);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you kill the part about making this a typed message? Dont we know what the string type is and you could just use:

logReport.Report(this._client.JsonSerializer.DeserialzeObject<Progress>(line);

var line = await reader.ReadLineAsync();
if (progress == null) continue;

var @event = JObject.Parse(line);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the complexity here? Cant JSON.NET just handle the deserialization in 1 object definition?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason is that I can't find the object structure well defined for those events in go files... So I got the fields that matter and manually read them. If you can point me to the right structure I can make it deserialize direct to the object just like in the others.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go ahead and leave this for now. I will remove it in the 1.13 branch that my PR eludes to because the type wasnt yet defined.


namespace Docker.DotNet.Models
{
public class EventMessage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. Add a line to specgen.go by /events
{reflect.TypeOf(events.Message{}), "EventsMessage"}, so that this stays in sync with the docker types. This will also generate for you the Actor struct etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok did some digging. I honestly cant tell from the docker code. I think we actually want jsonmessage.JsonMessage type here instead. @swernli does this seem right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will reflect the JSONError and JSONProgress structs too which is the full message as far as I can tell.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it from here https://github.com/docker/docker/blob/master/api/types/events/events.go which are the only objects used by this method. Do you want submit a PR with the Go stuff changed? I don't have it here and would take a while to get it working...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this in the other PR. Rebase on it and you can remove.

@galvesribeiro
Copy link
Member Author

@jterry75 done. Now only thing missing is that Go thing...

@galvesribeiro
Copy link
Member Author

@jterry75 ?

Copy link
Contributor

@jterry75 jterry75 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost! Thanks for doing this!

@@ -254,6 +256,21 @@ public Task<Stream> GetContainerLogsAsync(string id, ContainerLogsParameters par
return this._client.MakeRequestForStreamAsync(new[] { NoSuchContainerHandler }, HttpMethod.Get, $"containers/{id}/logs", queryParameters, null, cancellationToken);
}

public async Task GetContainerLogsAsync(string id, ContainerLogsParameters parameters, CancellationToken cancellationToken, IProgress<string> progress = null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this compile? I would assume that for this transfer period what we will need to do is to make the progress a non default parameter. Then we will have 2 physical overloads and then when I merge/remove the [Obsolete] version I will make it optional again to keep the same set of overloads.

var line = await reader.ReadLineAsync();
if (progress == null) continue;

var report = JsonConvert.DeserializeObject<ContainerStatsResponse>(line);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the this._client.JsonSerializer.DeserializeObject it makes it a whole lot easier for writing tests to not hard reference JsonConvert

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then you dont need the using at the top

@@ -40,6 +41,8 @@ public interface IContainerOperations

Task<Stream> GetContainerLogsAsync(string id, ContainerLogsParameters parameters, CancellationToken cancellationToken);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya now I think I mislead you. We only expose the Interfaces externally. I think you need to make the [Obsolete] tags here instead. My bad

var line = await reader.ReadLineAsync();
if (progress == null) continue;

var @event = JObject.Parse(line);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go ahead and leave this for now. I will remove it in the 1.13 branch that my PR eludes to because the type wasnt yet defined.

@@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using Docker.DotNet.Models;
using Newtonsoft.Json;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same. If you remove the JsonConvert reference and use this._client.JsonSerializer we can remove this too


namespace Docker.DotNet.Models
{
public class EventMessage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this in the other PR. Rebase on it and you can remove.

@@ -0,0 +1,9 @@
namespace Docker.DotNet.Models
{
public struct ImageOperationProgress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep for now. I will remove later in the 1.13 branch

@galvesribeiro
Copy link
Member Author

@jterry75 done :)

@jterry75 jterry75 merged commit e8d7f8b into dotnet:master Jan 19, 2017
mdarocha pushed a commit to TrapTech/Docker.DotNet that referenced this pull request Jul 11, 2022
mdarocha pushed a commit to TrapTech/Docker.DotNet that referenced this pull request Jul 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants