Skip to content

Commit

Permalink
Use loop not recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
dadgar committed Nov 16, 2015
1 parent b692bcd commit 9aa9a22
Showing 1 changed file with 73 additions and 70 deletions.
143 changes: 73 additions & 70 deletions client/task_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,90 +211,93 @@ func (r *TaskRunner) Run() {
r.logger.Printf("[DEBUG] client: starting task context for '%s' (alloc '%s')",
r.task.Name, r.allocID)

r.run(false)
r.run()
return
}

func (r *TaskRunner) run(forceStart bool) {
// Start the task if not yet started or it is being forced.
if r.handle == nil || forceStart {
if err := r.startTask(); err != nil {
return
}
}

// Store the errors that caused use to stop waiting for updates.
var waitRes *cstructs.WaitResult
var destroyErr error
destroyed := false

OUTER:
// Wait for updates
func (r *TaskRunner) run() {
var forceStart bool
for {
select {
case waitRes = <-r.handle.WaitCh():
break OUTER
case update := <-r.updateCh:
// Update
r.task = update
if err := r.handle.Update(update); err != nil {
r.logger.Printf("[ERR] client: failed to update task '%s' for alloc '%s': %v", r.task.Name, r.allocID, err)
// Start the task if not yet started or it is being forced.
if r.handle == nil || forceStart {
forceStart = false
if err := r.startTask(); err != nil {
return
}
case <-r.destroyCh:
// Send the kill signal, and use the WaitCh to block until complete
if err := r.handle.Kill(); err != nil {
r.logger.Printf("[ERR] client: failed to kill task '%s' for alloc '%s': %v", r.task.Name, r.allocID, err)
destroyErr = err
}

// Store the errors that caused use to stop waiting for updates.
var waitRes *cstructs.WaitResult
var destroyErr error
destroyed := false

OUTER:
// Wait for updates
for {
select {
case waitRes = <-r.handle.WaitCh():
break OUTER
case update := <-r.updateCh:
// Update
r.task = update
if err := r.handle.Update(update); err != nil {
r.logger.Printf("[ERR] client: failed to update task '%s' for alloc '%s': %v", r.task.Name, r.allocID, err)
}
case <-r.destroyCh:
// Send the kill signal, and use the WaitCh to block until complete
if err := r.handle.Kill(); err != nil {
r.logger.Printf("[ERR] client: failed to kill task '%s' for alloc '%s': %v", r.task.Name, r.allocID, err)
destroyErr = err
}
destroyed = true
}
destroyed = true
}
}

// If the user destroyed the task, we do not attempt to do any restarts.
if destroyed {
r.setState(structs.TaskStateDead, structs.NewTaskEvent(structs.TaskKilled).SetKillError(destroyErr))
return
}
// If the user destroyed the task, we do not attempt to do any restarts.
if destroyed {
r.setState(structs.TaskStateDead, structs.NewTaskEvent(structs.TaskKilled).SetKillError(destroyErr))
return
}

// Log whether the task was successful or not.
if !waitRes.Successful() {
r.logger.Printf("[ERR] client: failed to complete task '%s' for alloc '%s': %v", r.task.Name, r.allocID, waitRes)
} else {
r.logger.Printf("[INFO] client: completed task '%s' for alloc '%s'", r.task.Name, r.allocID)
}
// Log whether the task was successful or not.
if !waitRes.Successful() {
r.logger.Printf("[ERR] client: failed to complete task '%s' for alloc '%s': %v", r.task.Name, r.allocID, waitRes)
} else {
r.logger.Printf("[INFO] client: completed task '%s' for alloc '%s'", r.task.Name, r.allocID)
}

// Check if we should restart. If not mark task as dead and exit.
waitEvent := r.waitErrorToEvent(waitRes)
shouldRestart, when := r.restartTracker.nextRestart()
if !shouldRestart {
r.logger.Printf("[INFO] client: Not restarting task: %v for alloc: %v ", r.task.Name, r.allocID)
r.setState(structs.TaskStateDead, waitEvent)
return
}
// Check if we should restart. If not mark task as dead and exit.
waitEvent := r.waitErrorToEvent(waitRes)
shouldRestart, when := r.restartTracker.nextRestart()
if !shouldRestart {
r.logger.Printf("[INFO] client: Not restarting task: %v for alloc: %v ", r.task.Name, r.allocID)
r.setState(structs.TaskStateDead, waitEvent)
return
}

r.logger.Printf("[INFO] client: Restarting Task: %v", r.task.Name)
r.logger.Printf("[DEBUG] client: Sleeping for %v before restarting Task %v", when, r.task.Name)
r.setState(structs.TaskStatePending, waitEvent)
r.logger.Printf("[INFO] client: Restarting Task: %v", r.task.Name)
r.logger.Printf("[DEBUG] client: Sleeping for %v before restarting Task %v", when, r.task.Name)
r.setState(structs.TaskStatePending, waitEvent)

// Sleep but watch for destroy events.
select {
case <-time.After(when):
case <-r.destroyCh:
}
// Sleep but watch for destroy events.
select {
case <-time.After(when):
case <-r.destroyCh:
}

// Destroyed while we were waiting to restart, so abort.
r.destroyLock.Lock()
destroyed = r.destroy
r.destroyLock.Unlock()
if destroyed {
r.logger.Printf("[DEBUG] client: Not restarting task: %v because it's destroyed by user", r.task.Name)
r.setState(structs.TaskStateDead, structs.NewTaskEvent(structs.TaskKilled))
return
}
// Destroyed while we were waiting to restart, so abort.
r.destroyLock.Lock()
destroyed = r.destroy
r.destroyLock.Unlock()
if destroyed {
r.logger.Printf("[DEBUG] client: Not restarting task: %v because it's destroyed by user", r.task.Name)
r.setState(structs.TaskStateDead, structs.NewTaskEvent(structs.TaskKilled))
return
}

// Recurse on ourselves and force the start since we are restarting the task.
r.run(true)
// TODO: Alex
// Set force start because we are restarting the task.
forceStart = true
}
return
}

Expand Down

0 comments on commit 9aa9a22

Please sign in to comment.