-
Notifications
You must be signed in to change notification settings - Fork 616
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
Use assignments instead of tasks #1508
Changes from all commits
03f0729
d7695f3
ee24218
2a2ffed
e997eb2
4dc641a
3dd13bf
e92692a
c2d82f6
1eb3402
443a457
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ import ( | |
"errors" | ||
"time" | ||
|
||
"github.com/Sirupsen/logrus" | ||
"github.com/docker/swarmkit/api" | ||
"github.com/docker/swarmkit/log" | ||
"github.com/docker/swarmkit/protobuf/ptypes" | ||
|
@@ -31,26 +32,26 @@ type session struct { | |
conn *grpc.ClientConn | ||
addr string | ||
|
||
agent *Agent | ||
sessionID string | ||
session api.Dispatcher_SessionClient | ||
errs chan error | ||
messages chan *api.SessionMessage | ||
tasks chan *api.TasksMessage | ||
agent *Agent | ||
sessionID string | ||
session api.Dispatcher_SessionClient | ||
errs chan error | ||
messages chan *api.SessionMessage | ||
assignments chan *api.AssignmentsMessage | ||
|
||
registered chan struct{} // closed registration | ||
closed chan struct{} | ||
} | ||
|
||
func newSession(ctx context.Context, agent *Agent, delay time.Duration, sessionID string, description *api.NodeDescription) *session { | ||
s := &session{ | ||
agent: agent, | ||
sessionID: sessionID, | ||
errs: make(chan error, 1), | ||
messages: make(chan *api.SessionMessage), | ||
tasks: make(chan *api.TasksMessage), | ||
registered: make(chan struct{}), | ||
closed: make(chan struct{}), | ||
agent: agent, | ||
sessionID: sessionID, | ||
errs: make(chan error, 1), | ||
messages: make(chan *api.SessionMessage), | ||
assignments: make(chan *api.AssignmentsMessage), | ||
registered: make(chan struct{}), | ||
closed: make(chan struct{}), | ||
} | ||
peer, err := agent.config.Managers.Select() | ||
if err != nil { | ||
|
@@ -205,22 +206,68 @@ func (s *session) handleSessionMessage(ctx context.Context, msg *api.SessionMess | |
} | ||
|
||
func (s *session) watch(ctx context.Context) error { | ||
log.G(ctx).Debugf("(*session).watch") | ||
client := api.NewDispatcherClient(s.conn) | ||
watch, err := client.Tasks(ctx, &api.TasksRequest{ | ||
SessionID: s.sessionID}) | ||
if err != nil { | ||
return err | ||
} | ||
log := log.G(ctx).WithFields(logrus.Fields{"method": "(*session).watch"}) | ||
log.Debugf("") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what mean for the debugf log There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We wanted to log the call to |
||
var ( | ||
resp *api.AssignmentsMessage | ||
assignmentWatch api.Dispatcher_AssignmentsClient | ||
tasksWatch api.Dispatcher_TasksClient | ||
streamReference string | ||
tasksFallback bool | ||
err error | ||
) | ||
|
||
client := api.NewDispatcherClient(s.conn) | ||
for { | ||
resp, err := watch.Recv() | ||
if err != nil { | ||
return err | ||
// If this is the first time we're running the loop, or there was a reference mismatch | ||
// attempt to get the assignmentWatch | ||
if assignmentWatch == nil && !tasksFallback { | ||
assignmentWatch, err = client.Assignments(ctx, &api.AssignmentsRequest{SessionID: s.sessionID}) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
// We have an assignmentWatch, let's try to receive an AssignmentMessage | ||
if assignmentWatch != nil { | ||
// If we get a code = 12 desc = unknown method Assignments, try to use tasks | ||
resp, err = assignmentWatch.Recv() | ||
if err != nil { | ||
if grpc.Code(err) != codes.Unimplemented { | ||
return err | ||
} | ||
tasksFallback = true | ||
assignmentWatch = nil | ||
log.WithError(err).Infof("falling back to Tasks") | ||
} | ||
} | ||
|
||
// This code is here for backwards compatibility (so that newer clients can use the | ||
// older method Tasks) | ||
if tasksWatch == nil && tasksFallback { | ||
tasksWatch, err = client.Tasks(ctx, &api.TasksRequest{SessionID: s.sessionID}) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
if tasksWatch != nil { | ||
var taskResp *api.TasksMessage | ||
taskResp, err = tasksWatch.Recv() | ||
if err != nil { | ||
return err | ||
} | ||
resp = &api.AssignmentsMessage{Type: api.AssignmentsMessage_COMPLETE, UpdateTasks: taskResp.Tasks} | ||
} | ||
|
||
// If there seems to be a gap in the stream, let's break out of the inner for and | ||
// re-sync (by calling Assignments again). | ||
if streamReference != "" && streamReference != resp.AppliesTo { | ||
assignmentWatch = nil | ||
} else { | ||
streamReference = resp.ResultsIn | ||
} | ||
|
||
select { | ||
case s.tasks <- resp: | ||
case s.assignments <- resp: | ||
case <-s.closed: | ||
return errSessionClosed | ||
case <-ctx.Done(): | ||
|
@@ -231,7 +278,6 @@ func (s *session) watch(ctx context.Context) error { | |
|
||
// sendTaskStatus uses the current session to send the status of a single task. | ||
func (s *session) sendTaskStatus(ctx context.Context, taskID string, status *api.TaskStatus) error { | ||
|
||
client := api.NewDispatcherClient(s.conn) | ||
if _, err := client.UpdateTaskStatus(ctx, &api.UpdateTaskStatusRequest{ | ||
SessionID: s.sessionID, | ||
|
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.
There is now an error condition where the agent and dispatcher disagree on the assignment set. The session will need to be restarted to sync everything.
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.
session.go:watch()
deals with that (line 263)