Merge pull request #25400 from jsafrane/devel/operation-error

Automatic merge from submit-queue

Add specific error type for "operation already exists" error.

PersistentVolume controller needs to know why scheduling a new operation has failed - if the operation was already running or some other error happened.
This commit is contained in:
k8s-merge-robot 2016-06-09 03:28:16 -07:00
commit 4d430ba09c
2 changed files with 34 additions and 1 deletions

View File

@ -62,7 +62,7 @@ func (grm *goRoutineMap) Run(operationName string, operation func() error) error
defer grm.Unlock()
if grm.operations[operationName] {
// Operation with name exists
return fmt.Errorf("Failed to create operation with name %q. An operation with that name already exists.", operationName)
return newAlreadyExistsError(operationName)
}
grm.operations[operationName] = true
@ -86,3 +86,30 @@ func (grm *goRoutineMap) operationComplete(operationName string) {
func (grm *goRoutineMap) Wait() {
grm.wg.Wait()
}
// alreadyExistsError is specific error returned when NewGoRoutine()
// detects that operation with given name is already running.
type alreadyExistsError struct {
operationName string
}
var _ error = alreadyExistsError{}
func (err alreadyExistsError) Error() string {
return fmt.Sprintf("Failed to create operation with name %q. An operation with that name already exists", err.operationName)
}
func newAlreadyExistsError(operationName string) error {
return alreadyExistsError{operationName}
}
// IsAlreadyExists returns true if an error returned from NewGoRoutine indicates
// that operation with the same name already exists.
func IsAlreadyExists(err error) bool {
switch err.(type) {
case alreadyExistsError:
return true
default:
return false
}
}

View File

@ -125,6 +125,9 @@ func Test_NewGoRoutineMap_Negative_SecondOpBeforeFirstCompletes(t *testing.T) {
if err2 == nil {
t.Fatalf("NewGoRoutine did not fail. Expected: <Failed to create operation with name \"%s\". An operation with that name already exists.> Actual: <no error>", operationName)
}
if !IsAlreadyExists(err2) {
t.Fatalf("NewGoRoutine did not return alreadyExistsError, got: %v", err2)
}
}
func Test_NewGoRoutineMap_Positive_ThirdOpAfterFirstCompletes(t *testing.T) {
@ -147,6 +150,9 @@ func Test_NewGoRoutineMap_Positive_ThirdOpAfterFirstCompletes(t *testing.T) {
if err2 == nil {
t.Fatalf("NewGoRoutine did not fail. Expected: <Failed to create operation with name \"%s\". An operation with that name already exists.> Actual: <no error>", operationName)
}
if !IsAlreadyExists(err2) {
t.Fatalf("NewGoRoutine did not return alreadyExistsError, got: %v", err2)
}
// Act
operation1DoneCh <- true // Force operation1 to complete