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