agent/task/cancelflag.go (55 lines of code) (raw):
// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
// use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing
// permissions and limitations under the License.
// Package task contains a default implementation of the interfaces in the task package.
package task
import (
"sync"
)
// State represents the state of a job.
type State int
const (
// Canceled indicates a job for which cancellation has been requested.
Canceled State = 1
// Completed indicates a completed job.
Completed State = 2
// ShutDown indicates a job for which ShutDown has been requested.
ShutDown State = 3
)
// CancelFlag is an object that is passed to any job submitted to a task in order to
// communicated job cancellation. Job cancellation has to be cooperative.
type CancelFlag interface {
// Canceled returns true if a cancel or Shutdown has been requested, false otherwise.
// This method should be called periodically in the job.
Canceled() bool
// Set sets the state of this flag and wakes up waiting callers.
Set(state State)
// ShutDown returns true if a ShutDown has been requested, false otherwise.
// This method should be called periodically in the job.
ShutDown() bool
// State returns the current flag state
State() State
// Wait blocks the caller until either a cancel has been requested or the
// task has completed normally. Returns Canceled if cancel has been requested,
// or Completed if the task completed normally.
// This is intended to be used to wake up a job that may be waiting on some resources, as follows:
// The main job starts a go routine that calls Wait. The main job then does its processing.
// During processing the job may be waiting on certain events/conditions.
// In the go routine, once Wait returns, if the return value indicates that a cancel
// request has been received, the go routine wakes up the running job.
Wait() (state State)
}
// ChanneledCancelFlag is a default implementation of the task.CancelFlag interface.
type ChanneledCancelFlag struct {
state State
ch chan struct{}
closed bool
m sync.RWMutex
}
// NewChanneledCancelFlag creates a new instance of ChanneledCancelFlag.
func NewChanneledCancelFlag() *ChanneledCancelFlag {
flag := &ChanneledCancelFlag{ch: make(chan struct{})}
return flag
}
// Canceled returns true if this flag has been set to Cancel state, false otherwise.
func (t *ChanneledCancelFlag) Canceled() bool {
t.m.RLock()
defer t.m.RUnlock()
return t.state == Canceled
}
// ShutDown returns true if this flag has been set to ShutDown state, false otherwise.
func (t *ChanneledCancelFlag) ShutDown() bool {
t.m.RLock()
defer t.m.RUnlock()
return t.state == ShutDown
}
// State returns the current flag state.
func (t *ChanneledCancelFlag) State() State {
t.m.RLock()
defer t.m.RUnlock()
return t.state
}
// Wait blocks until the flag is set to either Cancel or Completed state. Returns the state.
func (t *ChanneledCancelFlag) Wait() (state State) {
<-t.ch
return t.State()
}
// Set sets the state of this flag and wakes up waiting callers.
func (t *ChanneledCancelFlag) Set(state State) {
t.m.Lock()
defer t.m.Unlock()
t.state = state
// close channel to wake up routines that are waiting
if !t.closed {
// avoid double closing, which would panic
close(t.ch)
t.closed = true
}
}