func registerHealthCheck(checks *sync.Map, name string, check HealthCheck, opts ...HealthCheckOption) {
	ctx := log.Logger().WithContext(context.Background())

	// create config based on defaults, then overwrite with given options
	hcCfg := HealthCheckCfg{
		interval:           cfg.Interval,
		initResultErrorTTL: cfg.HealthCheckInitResultErrorTTL,
		maxWait:            cfg.HealthCheckMaxWait,
	}
	for _, o := range opts {
		o(&hcCfg)
	}

	// check both lists, because
	if _, inReq := requiredChecks.Load(name); inReq {
		log.Warnf("tried to register health check with name %q twice", name)
		return
	}
	if _, inOpt := optionalChecks.Load(name); inOpt {
		log.Warnf("tried to register health check with name %q twice", name)
		return
	}

	// save the length of the longest health check name, for the width of the column in /health/check
	if len(name) > longestCheckName {
		longestCheckName = len(name)
	}
	var bgState ConnectionState
	checks.Store(name, &bgState)

	go func() {
		defer errors.HandleWithCtx(ctx, fmt.Sprintf("BackgroundHealthCheck %s", name))

		var (
			initHC, hasInitialization = check.(Initializable)
			initialized               = false
		)
		timer := time.NewTimer(0) // Do first health check instantly
		for {
			<-timer.C
			func() {
				defer errors.HandleWithCtx(ctx, fmt.Sprintf("BackgroundHealthCheck_HealthCheck %s", name))
				defer timer.Reset(hcCfg.interval)

				ctx, cancel := context.WithTimeout(ctx, hcCfg.maxWait)
				defer cancel()
				span, ctx := opentracing.StartSpanFromContext(ctx, "BackgroundHealthCheck")
				defer span.Finish()

				if hasInitialization && !initialized {
					if time.Since(bgState.LastChecked()) < hcCfg.initResultErrorTTL {
						// Too soon, leave the same state
						return
					}
					initErr := initHealthCheck(ctx, initHC)
					if initErr != nil {
						// Init failed again
						bgState.SetErrorState(initErr)
						return
					}

					initialized = true
					// Init succeeded, proceed with check
				}

				// Actual health check
				bgState.setConnectionState(check.HealthCheck(ctx))
			}()
		}
	}()
}
// registerHealthCheck will run the HealthCheck in the background.
registerHealthCheck will run the HealthCheck in the background.
// registerHealthCheck will run the HealthCheck in the background .
func registerHealthCheck(checks *sync.Map, name string, check HealthCheck, opts ...HealthCheckOption) {
	ctx := log.Logger().WithContext(context.Background())
	hcCfg := HealthCheckCfg{
		interval:           cfg.Interval,
		initResultErrorTTL: cfg.HealthCheckInitResultErrorTTL,
		maxWait:            cfg.HealthCheckMaxWait,
	}
	for _, o := range opts {
		o(&hcCfg)
	}
	if _, inReq := requiredChecks.Load(name); inReq {
		log.Warnf("tried to register health check with name %q twice", name)
		return
	}
	if _, inOpt := optionalChecks.Load(name); inOpt {
		log.Warnf("tried to register health check with name %q twice", name)
		return
	}
	if len(name) > longestCheckName {
		longestCheckName = len(name)
	}
	var bgState ConnectionState
	checks.Store(name, &bgState)
	go func() {
		defer errors.HandleWithCtx(ctx, fmt.Sprintf("BackgroundHealthCheck %s", name))
		var (
			initHC, hasInitialization = check.(Initializable)
			initialized               = false
		)
		timer := time.NewTimer(0) 
		for {
			<-timer.C
			func() {
				defer errors.HandleWithCtx(ctx, fmt.Sprintf("BackgroundHealthCheck_HealthCheck %s", name))
				defer timer.Reset(hcCfg.interval)
				ctx, cancel := context.WithTimeout(ctx, hcCfg.maxWait)
				defer cancel()
				span, ctx := opentracing.StartSpanFromContext(ctx, "BackgroundHealthCheck")
				defer span.Finish()
				if hasInitialization && !initialized {
					if time.Since(bgState.LastChecked()) < hcCfg.initResultErrorTTL {
						return
					}
					initErr := initHealthCheck(ctx, initHC)
					if initErr != nil {
						bgState.SetErrorState(initErr)
						return
					}
					initialized = true
				}
				bgState.setConnectionState(check.HealthCheck(ctx))
			}()
		}
	}()
}
func registerHealthCheck ( checks * sync . Map , name string , check HealthCheck , opts ... HealthCheckOption ) { ctx := log . Logger ( ) . WithContext ( context . Background ( ) ) hcCfg := HealthCheckCfg { interval : cfg . Interval , initResultErrorTTL : cfg . HealthCheckInitResultErrorTTL , maxWait : cfg . HealthCheckMaxWait , } for _ , o := range opts { o ( & hcCfg ) } if _ , inReq := requiredChecks . Load ( name ) ; inReq { log . Warnf ( " " , name ) return } if _ , inOpt := optionalChecks . Load ( name ) ; inOpt { log . Warnf ( " " , name ) return } if len ( name ) > longestCheckName { longestCheckName = len ( name ) } var bgState ConnectionState checks . Store ( name , & bgState ) go func ( ) { defer errors . HandleWithCtx ( ctx , fmt . Sprintf ( " " , name ) ) var ( initHC , hasInitialization = check . ( Initializable ) initialized = false ) timer := time . NewTimer ( 0 ) for { <- timer . C func ( ) { defer errors . HandleWithCtx ( ctx , fmt . Sprintf ( " " , name ) ) defer timer . Reset ( hcCfg . interval ) ctx , cancel := context . WithTimeout ( ctx , hcCfg . maxWait ) defer cancel ( ) span , ctx := opentracing . StartSpanFromContext ( ctx , " " ) defer span . Finish ( ) if hasInitialization && ! initialized { if time . Since ( bgState . LastChecked ( ) ) < hcCfg . initResultErrorTTL { return } initErr := initHealthCheck ( ctx , initHC ) if initErr != nil { bgState . SetErrorState ( initErr ) return } initialized = true } bgState . setConnectionState ( check . HealthCheck ( ctx ) ) } ( ) } } ( ) }
registerHealthCheck will run the HealthCheck in the background.
registerHealthCheck will run the HealthCheck in the background .
// create config based on defaults, then overwrite with given options // check both lists, because // save the length of the longest health check name, for the width of the column in /health/check // Do first health check instantly // Too soon, leave the same state // Init failed again // Init succeeded, proceed with check // Actual health check