From 29e057fa5db261db87d437c328127a42955bb623 Mon Sep 17 00:00:00 2001 From: ale Date: Fri, 14 Jun 2019 17:03:27 +0100 Subject: [PATCH] Add a way to trigger immediate backups Send SIGUSR1 to the agent binary. --- README.md | 4 ++++ agent.go | 5 +++++ cmd/tabacco/agent.go | 11 +++++++++++ jobs/scheduler.go | 15 +++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/README.md b/README.md index bc1929b..22daca1 100644 --- a/README.md +++ b/README.md @@ -252,6 +252,10 @@ and this dataset source: - name: db2 ``` +## Runtime signals + +The agent will reload its configuration on SIGHUP, and it will +immediately trigger all backup jobs upon receiving SIGUSR1. # TODO diff --git a/agent.go b/agent.go index 9bed899..6b9c707 100644 --- a/agent.go +++ b/agent.go @@ -95,3 +95,8 @@ func makeSchedule(ctx context.Context, m Manager, sourceSpecs []SourceSpec, host return sched, merr.OrNil() } + +// RunNow starts all jobs right now, regardless of their schedule. +func (a *Agent) RunNow() { + a.sched.RunNow() +} diff --git a/cmd/tabacco/agent.go b/cmd/tabacco/agent.go index bab39ea..e30e8cc 100644 --- a/cmd/tabacco/agent.go +++ b/cmd/tabacco/agent.go @@ -72,12 +72,23 @@ func (c *agentCommand) Execute(ctx context.Context, f *flag.FlagSet, args ...int return subcommands.ExitFailure } + // Build the Agent, and hook SIGUSR1 so that it triggers all + // the backup jobs immediately (useful for emergencies or + // debugging purposes). agent, err := tabacco.NewAgent(ctx, configMgr, store) if err != nil { log.Printf("error: %v", err) return subcommands.ExitFailure } defer agent.Close() // nolint + usr1Ch := make(chan os.Signal, 1) + go func() { + for range usr1Ch { + log.Printf("SIGUSR1 received, starting all jobs immediately") + agent.RunNow() + } + }() + signal.Notify(usr1Ch, syscall.SIGUSR1) log.Printf("backup agent started") diff --git a/jobs/scheduler.go b/jobs/scheduler.go index ee73731..27efdf7 100644 --- a/jobs/scheduler.go +++ b/jobs/scheduler.go @@ -194,6 +194,21 @@ func (s *Scheduler) Stop() { close(s.notifyCh) } +// RunNow starts all jobs right now, regardless of their schedule. +func (s *Scheduler) RunNow() { + s.mx.Lock() + defer s.mx.Unlock() + if s.cur == nil { + return + } + + for _, entry := range s.cur.c.Entries() { + go func(entry *cron.Entry) { + entry.Job.Run() + }(entry) + } +} + // CronJobStatus represents the status of a job, either scheduled, // running, or terminated in the past. type CronJobStatus struct { -- GitLab