Commit 29e057fa authored by ale's avatar ale

Add a way to trigger immediate backups

Send SIGUSR1 to the agent binary.
parent 6f7f5cb2
Pipeline #3435 passed with stages
in 1 minute and 55 seconds
...@@ -252,6 +252,10 @@ and this dataset source: ...@@ -252,6 +252,10 @@ and this dataset source:
- name: db2 - name: db2
``` ```
## Runtime signals
The agent will reload its configuration on SIGHUP, and it will
immediately trigger all backup jobs upon receiving SIGUSR1.
# TODO # TODO
......
...@@ -95,3 +95,8 @@ func makeSchedule(ctx context.Context, m Manager, sourceSpecs []SourceSpec, host ...@@ -95,3 +95,8 @@ func makeSchedule(ctx context.Context, m Manager, sourceSpecs []SourceSpec, host
return sched, merr.OrNil() return sched, merr.OrNil()
} }
// RunNow starts all jobs right now, regardless of their schedule.
func (a *Agent) RunNow() {
a.sched.RunNow()
}
...@@ -72,12 +72,23 @@ func (c *agentCommand) Execute(ctx context.Context, f *flag.FlagSet, args ...int ...@@ -72,12 +72,23 @@ func (c *agentCommand) Execute(ctx context.Context, f *flag.FlagSet, args ...int
return subcommands.ExitFailure 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) agent, err := tabacco.NewAgent(ctx, configMgr, store)
if err != nil { if err != nil {
log.Printf("error: %v", err) log.Printf("error: %v", err)
return subcommands.ExitFailure return subcommands.ExitFailure
} }
defer agent.Close() // nolint 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") log.Printf("backup agent started")
......
...@@ -194,6 +194,21 @@ func (s *Scheduler) Stop() { ...@@ -194,6 +194,21 @@ func (s *Scheduler) Stop() {
close(s.notifyCh) 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, // CronJobStatus represents the status of a job, either scheduled,
// running, or terminated in the past. // running, or terminated in the past.
type CronJobStatus struct { type CronJobStatus struct {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment