in swim/state_transitions.go [119:160]
func (s *stateTransitions) schedule(subject subject, state string, timeout time.Duration, transition func()) {
if !s.enabled {
s.logger.WithField("member", subject.address()).Warn("cannot schedule a state transition while disabled")
return
}
if s.node.Address() == subject.address() {
s.logger.WithField("member", subject.address()).Debug("cannot schedule a state transition for the local member")
return
}
if timer, ok := s.timers[subject.address()]; ok {
if timer.state == state {
s.logger.WithFields(bark.Fields{
"member": subject.address(),
"state": state,
}).Warn("redundant call to schedule a state transition for member, ignored")
return
}
// cancel the previously scheduled transition for the subject
timer.Stop()
}
timer := s.node.clock.AfterFunc(timeout, func() {
s.logger.WithFields(bark.Fields{
"member": subject.address(),
"state": state,
}).Info("executing scheduled transition for member")
// execute the transition
transition()
})
s.timers[subject.address()] = &transitionTimer{
Timer: timer,
state: state,
}
s.logger.WithFields(bark.Fields{
"member": subject.address(),
"state": state,
}).Debug("scheduled state transition for member")
}