interruptible_wait: allow nil Predicate

Allow for the case where InterruptibleWait is used purely for the
timeout.
See the documentation string for details.
This commit is contained in:
Cheng Sun 2014-12-09 14:55:35 +00:00
parent 651274e508
commit ba7c5ddcd2

View File

@ -6,9 +6,11 @@ import (
)
type InterruptibleWait struct {
Timeout time.Duration
// optional:
Predicate func() (result bool, err error)
PredicateInterval time.Duration
Timeout time.Duration
}
type TimeoutError struct{}
@ -28,11 +30,18 @@ type PredicateResult struct {
err error
}
/* Wait waits for up to Timeout duration, checking an optional Predicate every PredicateInterval duration.
The first run of Predicate is immediately after Wait is called.
If the command is interrupted by the user, then an InterruptedError is returned.
If Predicate is not nil, a timeout leads to TimeoutError being returned, and a successful Predicate run leads to nil being returned.
If Predicate is nil, a timeout is not an error, and nil is returned.
*/
func (wait InterruptibleWait) Wait(state multistep.StateBag) error {
predicateResult := make(chan PredicateResult, 1)
stopWaiting := make(chan struct{})
defer close(stopWaiting)
if wait.Predicate != nil {
go func() {
for {
if complete, err := wait.Predicate(); err != nil || complete {
@ -48,6 +57,7 @@ func (wait InterruptibleWait) Wait(state multistep.StateBag) error {
}
}
}()
}
timeout := time.After(wait.Timeout)
for {
@ -63,7 +73,11 @@ func (wait InterruptibleWait) Wait(state multistep.StateBag) error {
}
case <-timeout:
if wait.Predicate != nil {
return TimeoutError{}
} else {
return nil
}
}
}
}