Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support maximum daemon execution time #19

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"time"
)

func daemonRun(ctx context.Context, freq time.Duration, f func() error) {
func startDaemon(ctx context.Context, freq time.Duration, f func() error) {
ticker := time.NewTicker(freq)
defer ticker.Stop()

errLogF := func() {
err := f()
if err != nil {
if err != nil && ctx.Err() == nil {
fmt.Fprintln(os.Stderr, err)
}
}
Expand Down
2 changes: 2 additions & 0 deletions kubernetes/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ spec:
- --config
- /config/config.yaml
- --daemon
# Trigger restart after 24h to force Slack data and PagerDuty schedule updates.
- --daemon-max-execution-time=1440m
- --dry-run
volumeMounts:
- name: pdsync
Expand Down
50 changes: 27 additions & 23 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"os"
"os/signal"
"regexp"
"sync"
"syscall"
"time"

Expand All @@ -17,7 +16,8 @@ var (
pdToken string
slToken string
notAlphaNumRE = regexp.MustCompile(`[^[:alnum:]]`)
minDaemonUpdateFrequency = 1 * time.Minute
daemonMinUpdateFrequency = 1 * time.Minute
daemonMaxExecutionTime time.Duration
includePrivateChannels bool
)

Expand Down Expand Up @@ -99,6 +99,11 @@ By default, the program will terminate after a single run. Use the --daemon flag
Usage: "how often on-call schedules should be checked for changes (minimum is 1 minute)",
Destination: &p.daemonUpdateFrequency,
},
&cli.DurationFlag{
Name: "daemon-max-execution-time",
Usage: "time after which the daemon should self-terminate (default: never)",
Destination: &daemonMaxExecutionTime,
},
&cli.BoolFlag{
Name: "include-private-channels",
Usage: "update topics from rivate channels as well",
Expand Down Expand Up @@ -148,16 +153,17 @@ func realMain(p params) error {
return err
}

if p.daemonUpdateFrequency < minDaemonUpdateFrequency {
p.daemonUpdateFrequency = minDaemonUpdateFrequency
if p.daemonUpdateFrequency < daemonMinUpdateFrequency {
p.daemonUpdateFrequency = daemonMinUpdateFrequency
}

sp := syncerParams{
pdClient: newPagerDutyClient(pdToken),
slClient: newSlackMetaClient(slToken, includePrivateChannels),
}

ctx := context.Background()
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, os.Interrupt)
defer stop()

fmt.Println("Getting Slack users")
sp.slackUsers, err = sp.slClient.getSlackUsers(ctx)
Expand All @@ -173,9 +179,9 @@ func realMain(p params) error {
}
fmt.Printf("Found %d Slack user group(s)\n", len(sp.slackUserGroups))

slSyncs, err := sp.createSlackSyncs(context.TODO(), cfg)
slSyncs, err := sp.createSlackSyncs(ctx, cfg)
if err != nil {
return err
return fmt.Errorf("failed to create Slack syncs: %s", err)
}

syncer := newSyncer(sp)
Expand All @@ -187,23 +193,21 @@ func realMain(p params) error {
return runFunc()
}

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
stopCtx, cancel := context.WithCancel(context.Background())

go func() {
<-c
cancel()
}()
daemonCtx := ctx
if daemonMaxExecutionTime > 0 {
fmt.Printf("Setting maximum daemon execution time to %s\n", daemonMaxExecutionTime)
var cancel context.CancelFunc
daemonCtx, cancel = context.WithTimeout(ctx, daemonMaxExecutionTime)
defer cancel()
}

var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("Starting daemon")
daemonRun(stopCtx, p.daemonUpdateFrequency, runFunc)
}()
fmt.Println("Starting daemon")
startDaemon(daemonCtx, p.daemonUpdateFrequency, runFunc)

wg.Wait()
termMessage := "Daemon terminated"
if daemonCtx.Err() != nil && ctx.Err() == nil {
termMessage += " (maximum execution time has elapsed)"
}
fmt.Println(termMessage)
return nil
}
Loading