func (dfdd *dfddImpl) run() {
	ticker := common.NewTimer(stateMachineTickerInterval)
	for {
		select {
		case e := <-dfdd.inputListenerCh:
			dfdd.handleListenerEvent(common.InputServiceName, e)
		case e := <-dfdd.storeListenerCh:
			dfdd.handleListenerEvent(common.StoreServiceName, e)
		case <-ticker.C:
			dfdd.handleTicker()
			ticker.Reset(stateMachineTickerInterval)
		case <-dfdd.shutdownC:
			dfdd.shutdownWG.Done()
			return
		}
	}
}
run is the main event loop that receives
events from RingpopMonitor and triggers
node failed events to the event pipeline
package controllerhost
import (
	"sync"
	"sync/atomic"
	"time"
	"errors"
	"github.com/uber/cherami-server/common"
)
type (
	Dfdd interface {
		common.Daemon
		ReportHostGoingDown(service string, hostID string)
		GetHostState(service string, hostID string) (dfddHostState, time.Duration)
	}
	dfddHost struct {
		state               dfddHostState
		lastStateChangeTime int64
	}
	dfddImpl struct {
		started    int32
		shutdownC  chan struct{}
		shutdownWG sync.WaitGroup
		context    *Context
		inputListenerCh chan *common.RingpopListenerEvent
		storeListenerCh chan *common.RingpopListenerEvent
		inputHosts atomic.Value
		storeHosts atomic.Value
		timeSource common.TimeSource
	}
)
var errUnknownService = errors.New("dfdd: unknown service")
const (
	listenerChannelSize = 32
)
type dfddHostState int
const (
	dfddHostStateUnknown dfddHostState = iota
	dfddHostStateUP
	dfddHostStateGoingDown
	dfddHostStateDown
	dfddHostStateForgotten
	numDfddStates  
)
var dfddStateNames = [numDfddStates]string{
	"unknown",
	"up",
	"goingDown",
	"down",
	"forgotten",
}
const hostGoingDownEvent common.RingpopEventType = 99
const downToForgottenDuration = int64(time.Hour * 2)
const maxHostRestartDuration = 5 * time.Minute
const hostMapInitialCapacity = 8
var stateMachineTickerInterval = time.Minute * 5
func NewDfdd(context *Context, timeSource common.TimeSource) Dfdd {
	dfdd := &dfddImpl{
		context:         context,
		timeSource:      timeSource,
		shutdownC:       make(chan struct{}),
		inputListenerCh: make(chan *common.RingpopListenerEvent, listenerChannelSize),
		storeListenerCh: make(chan *common.RingpopListenerEvent, listenerChannelSize),
	}
	dfdd.inputHosts.Store(make(map[string]dfddHost, 8))
	dfdd.storeHosts.Store(make(map[string]dfddHost, 8))
	return dfdd
}
func (dfdd *dfddImpl) Start() {
	if !atomic.CompareAndSwapInt32(&dfdd.started, 0, 1) {
		dfdd.context.log.Fatal("dfdd daemon already started")
	}
	rpm := dfdd.context.rpm
	err := rpm.AddListener(common.InputServiceName, buildListenerName(common.InputServiceName), dfdd.inputListenerCh)
	if err != nil {
		dfdd.context.log.WithField(common.TagErr, err).Fatal(`rpm.addListener(inputhost) failed`)
		return
	}
	err = rpm.AddListener(common.StoreServiceName, buildListenerName(common.StoreServiceName), dfdd.storeListenerCh)
	if err != nil {
		dfdd.context.log.WithField(common.TagErr, err).Fatal(`rpm.addListener(storehost) failed`)
		return
	}
	dfdd.shutdownWG.Add(1)
	go dfdd.run()
	dfdd.context.log.Info("dfdd daemon started")
}
func (dfdd *dfddImpl) Stop() {
	close(dfdd.shutdownC)
	if !common.AwaitWaitGroup(&dfdd.shutdownWG, time.Second) {
		dfdd.context.log.Error("timed out waiting for dfdd daemon to stop")
	}
	dfdd.context.log.Info("dfdd daemon stopped")
}
func (dfdd *dfddImpl) GetHostState(service string, hostID string) (dfddHostState, time.Duration) {
	hosts, err := dfdd.getHosts(service)
	if err != nil {
		return dfddHostStateUnknown, time.Duration(0)
	}
	if curr, ok := hosts[hostID]; ok {
		now := dfdd.timeSource.Now().UnixNano()
		return curr.state, time.Duration(now - curr.lastStateChangeTime)
	}
	return dfddHostStateUnknown, time.Duration(0)
}
func (dfdd *dfddImpl) ReportHostGoingDown(service string, hostID string) {
	event := &common.RingpopListenerEvent{
		Key:  hostID,
		Type: hostGoingDownEvent,
	}
	switch service {
	case common.InputServiceName:
		dfdd.inputListenerCh <- event
		dfdd.context.log.WithField(common.TagIn, hostID).
			Info("input host reported as going down for planned maintenance")
	case common.StoreServiceName:
		dfdd.storeListenerCh <- event
		dfdd.context.log.WithField(common.TagStor, hostID).
			Info("store host reported as going down for planned maintenance")
	default:
		return
	}
}