@@ -279,6 +279,11 @@ type Coordinator struct {
279279
280280 // mx sync.RWMutex
281281 // protection protection.Config
282+
283+ // a sync channel that can be called by other components to check if the main coordinator
284+ // loop in runLoopIteration() is active and listening.
285+ // Should only be interacted with via CoordinatorActive() or runLoopIteration()
286+ heartbeatChan chan struct {}
282287}
283288
284289// The channels Coordinator reads to receive updates from the various managers.
@@ -372,6 +377,7 @@ func New(logger *logger.Logger, cfg *configuration.Configuration, logLevel logp.
372377 logLevelCh : make (chan logp.Level ),
373378 overrideStateChan : make (chan * coordinatorOverrideState ),
374379 upgradeDetailsChan : make (chan * details.Details ),
380+ heartbeatChan : make (chan struct {}),
375381 }
376382 // Setup communication channels for any non-nil components. This pattern
377383 // lets us transparently accept nil managers / simulated events during
@@ -412,6 +418,22 @@ func (c *Coordinator) State() State {
412418 return c .stateBroadcaster .Get ()
413419}
414420
421+ // CoordinatorActive is a blocking method that waits for a channel response
422+ // from the coordinator loop. This can be used to as a basic health check,
423+ // as we'll timeout and return false if the coordinator run loop doesn't
424+ // respond to our channel.
425+ func (c * Coordinator ) CoordinatorActive (timeout time.Duration ) bool {
426+ ctx , cancel := context .WithTimeout (context .Background (), timeout )
427+ defer cancel ()
428+
429+ select {
430+ case <- c .heartbeatChan :
431+ return true
432+ case <- ctx .Done ():
433+ return false
434+ }
435+ }
436+
415437func (c * Coordinator ) RegisterMonitoringServer (s configReloader ) {
416438 c .monitoringServerReloader = s
417439}
@@ -977,6 +999,8 @@ func (c *Coordinator) runLoopIteration(ctx context.Context) {
977999 case upgradeDetails := <- c .upgradeDetailsChan :
9781000 c .setUpgradeDetails (upgradeDetails )
9791001
1002+ case c .heartbeatChan <- struct {}{}:
1003+
9801004 case componentState := <- c .managerChans .runtimeManagerUpdate :
9811005 // New component change reported by the runtime manager via
9821006 // Coordinator.watchRuntimeComponents(), merge it with the
0 commit comments