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

External watch API #2034

Merged
merged 7 commits into from
Mar 30, 2017
Merged

External watch API #2034

merged 7 commits into from
Mar 30, 2017

Conversation

aaronlehmann
Copy link
Collaborator

@aaronlehmann aaronlehmann commented Mar 14, 2017

Add the first RPC from the external store API: Watch.

This RPC supports resuming from a known location, as well as starting the watch stream to only receive future events.

It can optionally return the old version of the object as well as the new one for Updates.

cc @dongluochen @aluzzardi

api/store.proto Outdated
StoreActionKind action = 1;

// Matched object
Object object = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can these be new and old or does that collide with a keyword?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think that would be overly specific to the "update" case. For example, if we're looking at a deletion, new wouldn't be the right field name for the object that was deleted.

@codecov
Copy link

codecov bot commented Mar 14, 2017

Codecov Report

Merging #2034 into master will increase coverage by 0.07%.
The diff coverage is 73.8%.

@@            Coverage Diff             @@
##           master    #2034      +/-   ##
==========================================
+ Coverage   54.28%   54.36%   +0.07%     
==========================================
  Files         111      113       +2     
  Lines       19327    19448     +121     
==========================================
+ Hits        10492    10572      +80     
- Misses       7569     7601      +32     
- Partials     1266     1275       +9

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6c388de...9472ac4. Read the comment docs.

@aaronlehmann
Copy link
Collaborator Author

Rebased

@dongluochen
Copy link
Contributor

Is it easy to make StoreActionKind a bitmap combination? For watch request, user can specify all events for service with StoreActionKindCreate | StoreActionKindUpdate | StoreActionKindRemove?

StoreActionKindCreate  StoreActionKind = 1
StoreActionKindUpdate  StoreActionKind = 2
StoreActionKindRemove  StoreActionKind = 4

@aaronlehmann
Copy link
Collaborator Author

Is it easy to make StoreActionKind a bitmap combination?

Good idea. Done in the most recent commit. Note that StoreActionKind can't be changed because it's part of the wire format, so this introduces a new WatchActionKind.

// Watch. Note that the first item of this stream will always be a WatchMessage
// with a nil Object, to signal that the stream has started.
message WatchMessage {
message Event {
Copy link
Contributor

Choose a reason for hiding this comment

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

Each Event should have a timestamp of commit time to store.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hm, this isn't currently available for historic events. For current Create and Update events, the individual objects will have the timestamp in Meta (but Delete events have the old timestamp).

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use the Meta timestamps.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should we omit it for delete events or include it even though it's the timestamp of the last update?

Copy link
Contributor

Choose a reason for hiding this comment

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

Each event needs a timestamp. I'll use the last UpdatedAt of delete events for now. Another option is to use the current time of machine.

@@ -0,0 +1,152 @@
syntax = "proto3";
Copy link
Member

Choose a reason for hiding this comment

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

I'd add a comment to everything that's not used

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure I follow. This isn't used yet - it's being added so that events can use it.

// previous version of the object on updates. Note that only live
// changes will include the old object (not historical changes
// retrieved using ResumeFrom).
bool include_old_object = 3;
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need for this to be an option rather than the default?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@dongluochen was concerned about wasted cycles and bandwidth sending two copies of the object for each change.

Copy link
Contributor

Choose a reason for hiding this comment

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

For Event, it need to include the old object to find the difference.

If an application just needs the current state and change as trigger, old object is not required. For example, if an application only cares about create and remove events. it doesn't need old object.

@aaronlehmann
Copy link
Collaborator Author

Rebased on #2039, and added code generation for all type-specific parts of this code. Now the only code in watch.go is a short gRPC stream endpoint. The actual code to build selectors and convert events is all generated.

@aaronlehmann
Copy link
Collaborator Author

Rebased

@dongluochen
Copy link
Contributor

LGTM

@dongluochen
Copy link
Contributor

Ping @docker/core-swarmkit-maintainers.

This is the first part of an external store API.

Watch returns a stream of new, updated, or removed objects matching the
given selectors.

Signed-off-by: Aaron Lehmann <[email protected]>
This adds a Version to every WatchMessage, and a ResumeFrom field in the
initial WatchRequest. A client can specify its last seen version to
avoid doing a complete resync.

Signed-off-by: Aaron Lehmann <[email protected]>
Signed-off-by: Aaron Lehmann <[email protected]>
@aaronlehmann
Copy link
Collaborator Author

Rebased

@diogomonica
Copy link
Contributor

@aaronlehmann do we filter secret data before we send those objects out?

@aaronlehmann
Copy link
Collaborator Author

No, this is not doing any redaction. It's the first piece of a store API, that will let external users interact with the data store at a lower level than the control API. I expect in the future there may be use cases where external controllers create and interact with secrets. We could always add redaction now, but might have to reconsider it later.

message StoreObject {
required WatchSelectors watch_selectors = 1;
Copy link
Member

Choose a reason for hiding this comment

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

is required still a thing in proto3?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This file doesn't use proto3 for whatever reason.

@aluzzardi
Copy link
Member

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants