github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/meterstatus/triggers.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package meterstatus
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/clock"
    10  )
    11  
    12  type TriggerCreator func(WorkerState, string, time.Time, clock.Clock, time.Duration, time.Duration) (<-chan time.Time, <-chan time.Time)
    13  
    14  // GetTriggers returns the signal channels for state transitions based on the current state.
    15  // It controls the transitions of the inactive meter status worker.
    16  //
    17  // In a simple case, the transitions are trivial:
    18  //
    19  // D------------------A----------------------R--------------------->
    20  //
    21  // D - disconnect time
    22  // A - amber status triggered
    23  // R - red status triggered
    24  //
    25  // The problem arises from the fact that the lifetime of the worker can
    26  // be interrupted, possibly with significant portions of the duration missing.
    27  func GetTriggers(
    28  	wst WorkerState,
    29  	status string,
    30  	disconnectedAt time.Time,
    31  	clk clock.Clock,
    32  	amberGracePeriod time.Duration,
    33  	redGracePeriod time.Duration) (<-chan time.Time, <-chan time.Time) {
    34  
    35  	now := clk.Now()
    36  
    37  	if wst == Done {
    38  		return nil, nil
    39  	}
    40  
    41  	if wst <= WaitingAmber && status == "RED" {
    42  		// If the current status is already RED, we don't want to deescalate.
    43  		wst = WaitingRed
    44  		//	} else if wst <= WaitingAmber && now.Sub(disconnectedAt) >= amberGracePeriod {
    45  		// If we missed the transition to amber, activate it.
    46  		//		wst = WaitingRed
    47  	} else if wst < Done && now.Sub(disconnectedAt) >= redGracePeriod {
    48  		// If we missed the transition to amber and it's time to transition to RED, go straight to RED.
    49  		wst = WaitingRed
    50  	}
    51  
    52  	if wst == WaitingRed {
    53  		redSignal := clk.After(redGracePeriod - now.Sub(disconnectedAt))
    54  		return nil, redSignal
    55  	}
    56  	if wst == WaitingAmber || wst == Uninitialized {
    57  		amberSignal := clk.After(amberGracePeriod - now.Sub(disconnectedAt))
    58  		redSignal := clk.After(redGracePeriod - now.Sub(disconnectedAt))
    59  		return amberSignal, redSignal
    60  	}
    61  	return nil, nil
    62  }