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

Check task dependencies before processing the task #796

Merged
merged 1 commit into from
May 24, 2017

Conversation

richardpen
Copy link

@richardpen richardpen commented May 10, 2017

Summary

Fix #756 Check the task dependencies before processing the task and provide a more clear log message.

Implementation details

Check the dependencies before processing the task in task engine.

Testing

  • Builds on Linux (make release)
  • Builds on Windows (go build -out amazon-ecs-agent.exe ./agent)
  • Unit tests on Linux (make test) pass
  • Unit tests on Windows (go test -timeout=25s ./agent/...) pass
  • Integration tests on Linux (make run-integ-tests) pass
  • Integration tests on Windows (.\scripts\run-integ-tests.ps1) pass
  • Functional tests on Linux (make run-functional-tests) pass
  • Functional tests on Windows (.\scripts\run-functional-tests.ps1) pass

New tests cover the changes:
yes

Description for the changelog

Licensing

This contribution is under the terms of the Apache 2.0 License:
yes

@@ -1146,3 +1146,27 @@ func TestEngineDisableConcurrentPull(t *testing.T) {
assert.False(t, dockerTaskEngine.enableConcurrentPull,
"Task engine should not be able to perform concurrent pulling for version < 1.11.1")
}

// TestTaskWithCircularDependency tests the task with containers of which the
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 also add a unit test in dependencygraph for ValidDependencies() to test a task with circular dependencies?

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Indeed, this sort of cyclical dependency is being tested here.

seelog.Errorf("Task can not move forward due to the dependencies of containers cannot be resolved, task:%s", task.String())
task.SetKnownStatus(api.TaskStopped)
task.SetDesiredStatus(api.TaskStopped)
engine.emitTaskEvent(task, "TaskTransitionError: Can not resolve the dependencies of containers in the task definition")
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 impossibleTransitionError type here instead?

if dependencygraph.ValidDependencies(task) {
engine.startTask(task)
} else {
seelog.Errorf("Task can not move forward due to the dependencies of containers cannot be resolved, task:%s", task.String())
Copy link
Contributor

Choose a reason for hiding this comment

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

We should either use can not or cannot. Let's not use both. I'd vote for cannot. Also, can you leave a space after task: ?

engine.state.AddTask(task)
engine.startTask(task)
if dependencygraph.ValidDependencies(task) {
engine.startTask(task)
Copy link
Contributor

Choose a reason for hiding this comment

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

you can also just return nil here and get rid of else in line 464.

Copy link
Contributor

Choose a reason for hiding this comment

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

@aaithal Can you explain that? There is no codepath where we could call AddTask on an existing task?

Copy link
Author

Choose a reason for hiding this comment

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

I think @aaithal means get rid of the else word but keeps the statement inside the else, see my updates.

engine.state.AddTask(task)
engine.startTask(task)
if dependencygraph.ValidDependencies(task) {
engine.startTask(task)
Copy link
Contributor

Choose a reason for hiding this comment

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

@aaithal Can you explain that? There is no codepath where we could call AddTask on an existing task?

seelog.Errorf("Task can not move forward due to the dependencies of containers cannot be resolved, task:%s", task.String())
task.SetKnownStatus(api.TaskStopped)
task.SetDesiredStatus(api.TaskStopped)
engine.emitTaskEvent(task, "TaskTransitionError: Can not resolve the dependencies of containers in the task definition")
Copy link
Contributor

Choose a reason for hiding this comment

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

Cannot vs. Can not. Cannot is "more correct"

@richardpen richardpen force-pushed the issue-756 branch 2 times, most recently from 1a9e032 to 2c88b2f Compare May 23, 2017 20:01
@vsiddharth
Copy link
Contributor

@richardpen these changes look good to me

seelog.Errorf("Task cannot move forward due to the dependencies of containers cannot be resolved, task: %s", task.String())
task.SetKnownStatus(api.TaskStopped)
task.SetDesiredStatus(api.TaskStopped)
engine.emitTaskEvent(task, "impossibleTransitionError: Cannot resolve the dependencies of containers in the task definition")
Copy link
Contributor

Choose a reason for hiding this comment

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

Apologies, I should have made this clearer in my earlier comment. Please use the impossibleTransitionError type instead:

type impossibleTransitionError struct {
instead.


// ErrorName is the name of the error
func (err TaskCircularDependencyError) ErrorName() string {
return "TAskCircularDependencyError"
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: "Task"

@@ -112,6 +112,21 @@ func (CannotGetDockerClientError) ErrorName() string {
return "CannotGetDockerclientError"
}

// TaskCircularDependencyError is the error for task that dependencies can't
// be resolved
type TaskCircularDependencyError struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if TaskDependencyError is a better type name. Because, the ValidDependencies method might fail for other reasons as well.

@richardpen richardpen merged commit fc7b501 into aws:dev May 24, 2017
if dependencygraph.ValidDependencies(task) {
engine.startTask(task)
} else {
seelog.Errorf("Task cannot move forward due to the dependencies of containers cannot be resolved, task: %s", task.String())
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 rephrase this? "Unable to progress task with circular dependencies"

}

func (err TaskDependencyError) Error() string {
return "Task dependencies cannot be resolved" + err.taskArn
Copy link
Contributor

Choose a reason for hiding this comment

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

You need a space at the end here or you'll end up with "resolvedarn:"

@samuelkarp samuelkarp added this to the 1.14.2 milestone May 25, 2017
@adnxn adnxn mentioned this pull request May 26, 2017
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.

6 participants