-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Events Service #956
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
Events Service #956
Conversation
cmd/ctr/events.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to follow the format of the type urls prescribed in google protobuf. I'll try to hunt down a link, but let's see if you find the right one! ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing I could find was https://github.com/containerd/containerd/blob/master/services/containers/helpers.go#L30. But that just specifies the TypeUrl as the version which is then the same for everything. Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've filed #960 to hunt this down. It includes a link to the correct destination, although, google provides pretty poor tooling for getting this right.
events/poster.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The poster shouldn't really have access to the envelope type. The envelope needs to be created by the poster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah ok makes sense
cmd/ctr/events.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could still have TIMESTAMP\tTOPIC\tEVENT or something similar :)
events/emitter.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can be done directly when assigning to listeners below
cmd/ctr/events.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the result of that Unmarshalling, if successful, is never used, is something missing?
api/types/event/event.proto
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: misaligned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gah i need to grab someone's vim config as these always misalign for me! ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this is aligned now...
62e0dfa to
d785898
Compare
Codecov Report
@@ Coverage Diff @@
## master #956 +/- ##
=======================================
Coverage 59.28% 59.28%
=======================================
Files 5 5
Lines 781 781
=======================================
Hits 463 463
Misses 204 204
Partials 114 114Continue to review full report at Codecov.
|
|
This has events for the following services:
As well as the runtime. I think this is complete for this PR. We can add to others in follow ups if desired. |
|
I think the last item for discussion is whether we want to include the namespace as part of the topic path or not: |
|
@ehazlett if we go including the namespace as part of the topic path, are operations affecting them to be shown as Also thinking of filtering, if I want to request all container events across namespaces, how would I do so With the field and no namespace as part of the topic, it'd just be |
|
Ya let's remove it. They will just be |
|
@ehazlett @mlaventure The namespace should be part of the request context, such that you do a new request for each namespace. This should elide the need for namespace fields. Are there problems with this approach that I'm missing? |
|
@stevvooe Do you mean when we request for event? In that case, I guess it's fine yes, as long as I can send a request with an empty namespace and get events across all of those. When streaming the event however, I don't think you can get a different header for each event sent, can you? |
|
@stevvooe the field we're talking about here is the field that's sent to the client as part of the event data (not internal). originally i mistakenly sent the namespace with the event. i've updated to have the namespace as part of the Envelope that the emitter adds so no service sends a namespace. thx! |
services/events/service.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should only emit events from a single namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated to make the client stream to only receive events from the client namespace.
api/types/event/snapshot.proto
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we declare these types in the package that emits the events, along with the service?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't matter to me. I kept them in the events type package to make it logical for events but I could see it in the others too. I don't have a strong feeling either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking at this, these should be declared by the services that emit them, rather than the event package. I'm not sure we need a secondary events package. The envelope can be part of the events service and the other events can be part of the services that emit them.
services/namespaces/service.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Namespaces can also be created implicitly, when in use. This makes it easy to just start using the API, but we never call into the a namespace service or store to make this happen.
cmd/ctr/events.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is simple string concatenation, so it could be "id="+e.ContainerID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to do a lot more -- I'll simpify 👍
events/emitter.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't some synchronization necessary on the various methods that use listeners? It looks like these are invoked from different goroutines.
events/emitter.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like a slow or unresponsive listener will block the other listeners from receiving events. See docker-archive/classicswarm#2718 for an example of a similar problem in classic Swarm.
Should this use go-events instead so the events are broadcasted to all listeners in a nonblocking fashion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't aware of go-events. I'll look thx.
events/emitter.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The broadcaster needs to be closed when you're done using it. Otherwise, it leaks a goroutine.
We use this wrapper in swarmkit, which may be helpful as an example: https://github.com/docker/swarmkit/blob/master/watch/watch.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a Close for the emitter to close this.
events/emitter.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this needs to be a pointer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unclear on what the mutex is used for. It doesn't seem to be protecting sinks, because the presence in the map is always tested before acquiring the mutex. But I don't think any locking is needed for broadcaster.Add and broadcaster.Remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated to acquire before testing and holds when creating a new broadcaster. If we don't need any locking for the broadcaster I believe that's the only thing that is mutated outside of the broadcaster so we could probably just remove it. wdyt?
events/emitter.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This read from the map is not protected by the mutex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ugh ok i'll step back and go over it better. sorry for the churn.
Signed-off-by: Evan Hazlett <[email protected]> events: update events package to include emitter and use envelope proto Signed-off-by: Evan Hazlett <[email protected]> events: add events service Signed-off-by: Evan Hazlett <[email protected]> events: enable events service and update ctr events to use events service Signed-off-by: Evan Hazlett <[email protected]> event listeners Signed-off-by: Evan Hazlett <[email protected]> events: helper func for emitting in services Signed-off-by: Evan Hazlett <[email protected]> events: improved cli for containers and tasks Signed-off-by: Evan Hazlett <[email protected]> create event envelope with poster Signed-off-by: Evan Hazlett <[email protected]> events: introspect event data to use for type url Signed-off-by: Evan Hazlett <[email protected]> events: use pb encoding; add event types Signed-off-by: Evan Hazlett <[email protected]> events: instrument content and snapshot services with events Signed-off-by: Evan Hazlett <[email protected]> events: instrument image service with events Signed-off-by: Evan Hazlett <[email protected]> events: instrument namespace service with events Signed-off-by: Evan Hazlett <[email protected]> events: add namespace support Signed-off-by: Evan Hazlett <[email protected]> events: only send events from namespace requested from client Signed-off-by: Evan Hazlett <[email protected]> events: switch to go-events for broadcasting Signed-off-by: Evan Hazlett <[email protected]>
|
ping @aaronlehmann @stevvooe |
| @@ -0,0 +1,13 @@ | |||
| syntax = "proto3"; | |||
|
|
|||
| package containerd.v1.types; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be containerd.v1.types.events?
|
LGTM I think we can handle the package organization in another pass. |
cmd/ctr/events.go
Outdated
| if err := proto.Unmarshal(evt.Event.Value, e); err != nil { | ||
| return out, err | ||
| } | ||
| out = fmt.Sprintf("id=%s", e.ContainerID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More Sprintf abuse :) (and other instances below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaronlehmann what is Sprintf abuse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using it to concatenate two strings instead of the + operator.
events/emitter.go
Outdated
| e.m.Unlock() | ||
| } | ||
|
|
||
| func (e *Emitter) Close() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this called?
| event Event | ||
| } | ||
|
|
||
| type eventSink struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be replaced by a combination of events.Chanel and events.Filter?
events.Channel gracefully handles closes when there are writes outstanding. It looks like this implementation wouldn't. If we can provide a guarantee that Close will never cross with a Write, it doesn't matter, but I'm not sure we can.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to take another pass here when filters are integrated. Could we fix this at that time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds okay. I don't see this Close method being called currently. Maybe we should remove it for now to avoid a possible "write to closed channel" panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's there to satisfy the sink interface anyway. I'll remove closing the channel.
Signed-off-by: Evan Hazlett <[email protected]>
|
LGTM |
This adds support for events across containerd services.
Example:
This closes #785