2021-01-26 13:56:20 +01:00
|
|
|
package process
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-03-25 13:24:21 +01:00
|
|
|
"fmt"
|
2021-01-26 13:56:20 +01:00
|
|
|
"sync"
|
2022-03-25 13:24:21 +01:00
|
|
|
|
|
|
|
"github.com/getsentry/sentry-go"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"go.uber.org/atomic"
|
2021-01-26 13:56:20 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type ProcessContext struct {
|
|
|
|
wg *sync.WaitGroup // used to wait for components to shutdown
|
|
|
|
ctx context.Context // cancelled when Stop is called
|
|
|
|
shutdown context.CancelFunc // shut down Dendrite
|
2022-03-25 13:24:21 +01:00
|
|
|
degraded atomic.Bool
|
2021-01-26 13:56:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewProcessContext() *ProcessContext {
|
|
|
|
ctx, shutdown := context.WithCancel(context.Background())
|
|
|
|
return &ProcessContext{
|
|
|
|
ctx: ctx,
|
|
|
|
shutdown: shutdown,
|
|
|
|
wg: &sync.WaitGroup{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *ProcessContext) Context() context.Context {
|
|
|
|
return context.WithValue(b.ctx, "scope", "process") // nolint:staticcheck
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *ProcessContext) ComponentStarted() {
|
|
|
|
b.wg.Add(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *ProcessContext) ComponentFinished() {
|
|
|
|
b.wg.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *ProcessContext) ShutdownDendrite() {
|
|
|
|
b.shutdown()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *ProcessContext) WaitForShutdown() <-chan struct{} {
|
|
|
|
return b.ctx.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *ProcessContext) WaitForComponentsToFinish() {
|
|
|
|
b.wg.Wait()
|
|
|
|
}
|
2022-03-25 13:24:21 +01:00
|
|
|
|
|
|
|
func (b *ProcessContext) Degraded() {
|
|
|
|
if b.degraded.CAS(false, true) {
|
|
|
|
logrus.Warn("Dendrite is running in a degraded state")
|
|
|
|
sentry.CaptureException(fmt.Errorf("Process is running in a degraded state"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *ProcessContext) IsDegraded() bool {
|
|
|
|
return b.degraded.Load()
|
|
|
|
}
|