// NewHealthManager implements the Store interface. It creates a new HealthManager that // uses the Consul Key-Value store to hold app health statues. func (c consulStore) newSessionHealthManager( node types.NodeName, logger logging.Logger, ) HealthManager { // Create a stream of sessions sessionChan := make(chan string) done := make(chan struct{}) // Current time of "Jan 2, 15:04:05" turns into "0102-150405" timeStr := time.Now().Format("0102-150405") go consulutil.SessionManager( api.SessionEntry{ Name: fmt.Sprintf("health:%s:%d:%s", node, os.Getpid(), timeStr), LockDelay: 1 * time.Millisecond, Behavior: api.SessionBehaviorDelete, TTL: fmt.Sprintf("%ds", *SessionTTLSec), }, c.client, sessionChan, done, logger, ) // Hook the session stream into a publisher pub := stream.NewStringValuePublisher(sessionChan, "") return &consulHealthManager{ sessionPub: pub, done: done, client: c.client, node: node, logger: logger, } }
func (r RCtl) Farm() { sessions := make(chan string) go kp.ConsulSessionManager(api.SessionEntry{ LockDelay: 1 * time.Nanosecond, Behavior: api.SessionBehaviorDelete, TTL: "15s", }, r.baseClient, sessions, nil, r.logger) firstSession := <-sessions pub := stream.NewStringValuePublisher(sessions, firstSession) rcSub := pub.Subscribe(nil) rlSub := pub.Subscribe(nil) go rc.NewFarm(r.kps, r.rcs, r.sched, r.labeler, rcSub.Chan(), r.logger).Start(nil) roll.NewFarm(roll.UpdateFactory{ KPStore: r.kps, RCStore: r.rcs, HealthChecker: r.hcheck, Labeler: r.labeler, Scheduler: r.sched, }, r.kps, r.rls, r.rcs, rlSub.Chan(), r.logger).Start(nil) }
func main() { // Parse custom flags + standard Consul routing options kingpin.Version(version.VERSION) _, opts := flags.ParseWithConsulOptions() // Set up the logger logger := logging.NewLogger(logrus.Fields{}) logger.Logger.Formatter = new(logrus.TextFormatter) if *logLevel != "" { lv, err := logrus.ParseLevel(*logLevel) if err != nil { logger.WithErrorAndFields(err, logrus.Fields{"level": *logLevel}). Fatalln("Could not parse log level") } logger.Logger.Level = lv } // Initialize the myriad of different storage components httpClient := cleanhttp.DefaultClient() client := kp.NewConsulClient(opts) kpStore := kp.NewConsulStore(client) rcStore := rcstore.NewConsul(client, RetryCount) rollStore := rollstore.NewConsul(client, nil) healthChecker := checker.NewConsulHealthChecker(client) labeler := labels.NewConsulApplicator(client, RetryCount) var sched scheduler.Scheduler if *labelEndpoint != "" { endpoint, err := url.Parse(*labelEndpoint) if err != nil { logger.WithErrorAndFields(err, logrus.Fields{ "url": *labelEndpoint, }).Fatalln("Could not parse URL from label endpoint") } httpLabeler, err := labels.NewHttpApplicator(opts.Client, endpoint) if err != nil { logger.WithError(err).Fatalln("Could not create label applicator from endpoint") } sched = scheduler.NewApplicatorScheduler(httpLabeler) } else { sched = scheduler.NewApplicatorScheduler(labeler) } // Start acquiring sessions sessions := make(chan string) go consulutil.SessionManager(api.SessionEntry{ Name: SessionName(), LockDelay: 5 * time.Second, Behavior: api.SessionBehaviorDelete, TTL: "15s", }, client, sessions, nil, logger) pub := stream.NewStringValuePublisher(sessions, "") alerter := alerting.NewNop() if *pagerdutyServiceKey != "" { var err error alerter, err = alerting.NewPagerduty(*pagerdutyServiceKey, httpClient) if err != nil { logger.WithError(err).Fatalln( "Unable to initialize pagerduty alerter", ) } } // Run the farms! go rc.NewFarm( kpStore, rcStore, sched, labeler, pub.Subscribe().Chan(), logger, klabels.Everything(), alerter, ).Start(nil) roll.NewFarm( roll.UpdateFactory{ KPStore: kpStore, RCStore: rcStore, HealthChecker: healthChecker, Labeler: labeler, Scheduler: sched, }, kpStore, rollStore, rcStore, pub.Subscribe().Chan(), logger, labeler, klabels.Everything(), alerter, ).Start(nil) }