mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-25 09:54:47 +01:00
move wakeup subcommand into signal subcommand and add reset subcommand
This commit is contained in:
parent
025fbda984
commit
89e0103abd
@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/zrepl/zrepl/daemon"
|
"github.com/zrepl/zrepl/daemon"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunWakeup(config *config.Config, args []string) error {
|
func RunSignal(config *config.Config, args []string) error {
|
||||||
if len(args) != 1 {
|
if len(args) != 2 {
|
||||||
return errors.Errorf("Expected 1 argument: job")
|
return errors.Errorf("Expected 2 arguments: [wakeup|reset] JOB")
|
||||||
}
|
}
|
||||||
|
|
||||||
httpc, err := controlHttpClient(config.Global.Control.SockPath)
|
httpc, err := controlHttpClient(config.Global.Control.SockPath)
|
||||||
@ -16,11 +16,13 @@ func RunWakeup(config *config.Config, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = jsonRequestResponse(httpc, daemon.ControlJobEndpointWakeup,
|
err = jsonRequestResponse(httpc, daemon.ControlJobEndpointSignal,
|
||||||
struct {
|
struct {
|
||||||
Name string
|
Name string
|
||||||
|
Op string
|
||||||
}{
|
}{
|
||||||
Name: args[0],
|
Name: args[1],
|
||||||
|
Op: args[0],
|
||||||
},
|
},
|
||||||
struct{}{},
|
struct{}{},
|
||||||
)
|
)
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/zrepl/zrepl/daemon/job"
|
"github.com/zrepl/zrepl/daemon/job"
|
||||||
@ -65,7 +66,7 @@ const (
|
|||||||
ControlJobEndpointPProf string = "/debug/pprof"
|
ControlJobEndpointPProf string = "/debug/pprof"
|
||||||
ControlJobEndpointVersion string = "/version"
|
ControlJobEndpointVersion string = "/version"
|
||||||
ControlJobEndpointStatus string = "/status"
|
ControlJobEndpointStatus string = "/status"
|
||||||
ControlJobEndpointWakeup string = "/wakeup"
|
ControlJobEndpointSignal string = "/signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (j *controlJob) Run(ctx context.Context) {
|
func (j *controlJob) Run(ctx context.Context) {
|
||||||
@ -104,17 +105,26 @@ func (j *controlJob) Run(ctx context.Context) {
|
|||||||
return s, nil
|
return s, nil
|
||||||
}}})
|
}}})
|
||||||
|
|
||||||
mux.Handle(ControlJobEndpointWakeup,
|
mux.Handle(ControlJobEndpointSignal,
|
||||||
requestLogger{log: log, handler: jsonRequestResponder{func(decoder jsonDecoder) (interface{}, error) {
|
requestLogger{log: log, handler: jsonRequestResponder{func(decoder jsonDecoder) (interface{}, error) {
|
||||||
type reqT struct {
|
type reqT struct {
|
||||||
Name string
|
Name string
|
||||||
|
Op string
|
||||||
}
|
}
|
||||||
var req reqT
|
var req reqT
|
||||||
if decoder(&req) != nil {
|
if decoder(&req) != nil {
|
||||||
return nil, errors.Errorf("decode failed")
|
return nil, errors.Errorf("decode failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := j.jobs.wakeup(req.Name)
|
var err error
|
||||||
|
switch req.Op {
|
||||||
|
case "wakeup":
|
||||||
|
err = j.jobs.wakeup(req.Name)
|
||||||
|
case "reset":
|
||||||
|
err = j.jobs.reset(req.Name)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("operation %q is invalid", req.Op)
|
||||||
|
}
|
||||||
|
|
||||||
return struct{}{}, err
|
return struct{}{}, err
|
||||||
}}})
|
}}})
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/zrepl/zrepl/config"
|
"github.com/zrepl/zrepl/config"
|
||||||
"github.com/zrepl/zrepl/daemon/job"
|
"github.com/zrepl/zrepl/daemon/job"
|
||||||
|
"github.com/zrepl/zrepl/daemon/job/reset"
|
||||||
"github.com/zrepl/zrepl/daemon/job/wakeup"
|
"github.com/zrepl/zrepl/daemon/job/wakeup"
|
||||||
"github.com/zrepl/zrepl/daemon/logging"
|
"github.com/zrepl/zrepl/daemon/logging"
|
||||||
"github.com/zrepl/zrepl/logger"
|
"github.com/zrepl/zrepl/logger"
|
||||||
@ -102,12 +103,14 @@ type jobs struct {
|
|||||||
// m protects all fields below it
|
// m protects all fields below it
|
||||||
m sync.RWMutex
|
m sync.RWMutex
|
||||||
wakeups map[string]wakeup.Func // by Job.Name
|
wakeups map[string]wakeup.Func // by Job.Name
|
||||||
|
resets map[string]reset.Func // by Job.Name
|
||||||
jobs map[string]job.Job
|
jobs map[string]job.Job
|
||||||
}
|
}
|
||||||
|
|
||||||
func newJobs() *jobs {
|
func newJobs() *jobs {
|
||||||
return &jobs{
|
return &jobs{
|
||||||
wakeups: make(map[string]wakeup.Func),
|
wakeups: make(map[string]wakeup.Func),
|
||||||
|
resets: make(map[string]reset.Func),
|
||||||
jobs: make(map[string]job.Job),
|
jobs: make(map[string]job.Job),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,6 +166,17 @@ func (s *jobs) wakeup(job string) error {
|
|||||||
return wu()
|
return wu()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *jobs) reset(job string) error {
|
||||||
|
s.m.RLock()
|
||||||
|
defer s.m.RUnlock()
|
||||||
|
|
||||||
|
wu, ok := s.resets[job]
|
||||||
|
if !ok {
|
||||||
|
return errors.Errorf("Job %s does not exist", job)
|
||||||
|
}
|
||||||
|
return wu()
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
jobNamePrometheus = "_prometheus"
|
jobNamePrometheus = "_prometheus"
|
||||||
jobNameControl = "_control"
|
jobNameControl = "_control"
|
||||||
@ -195,7 +209,9 @@ func (s *jobs) start(ctx context.Context, j job.Job, internal bool) {
|
|||||||
s.jobs[jobName] = j
|
s.jobs[jobName] = j
|
||||||
ctx = job.WithLogger(ctx, jobLog)
|
ctx = job.WithLogger(ctx, jobLog)
|
||||||
ctx, wakeup := wakeup.Context(ctx)
|
ctx, wakeup := wakeup.Context(ctx)
|
||||||
|
ctx, resetFunc := reset.Context(ctx)
|
||||||
s.wakeups[jobName] = wakeup
|
s.wakeups[jobName] = wakeup
|
||||||
|
s.resets[jobName] = resetFunc
|
||||||
|
|
||||||
s.wg.Add(1)
|
s.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/problame/go-streamrpc"
|
"github.com/problame/go-streamrpc"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/zrepl/zrepl/config"
|
"github.com/zrepl/zrepl/config"
|
||||||
|
"github.com/zrepl/zrepl/daemon/job/reset"
|
||||||
"github.com/zrepl/zrepl/daemon/job/wakeup"
|
"github.com/zrepl/zrepl/daemon/job/wakeup"
|
||||||
"github.com/zrepl/zrepl/daemon/transport/connecter"
|
"github.com/zrepl/zrepl/daemon/transport/connecter"
|
||||||
"github.com/zrepl/zrepl/daemon/filters"
|
"github.com/zrepl/zrepl/daemon/filters"
|
||||||
@ -248,6 +249,21 @@ func (j *ActiveSide) do(ctx context.Context) {
|
|||||||
log := GetLogger(ctx)
|
log := GetLogger(ctx)
|
||||||
ctx = logging.WithSubsystemLoggers(ctx, log)
|
ctx = logging.WithSubsystemLoggers(ctx, log)
|
||||||
|
|
||||||
|
// allow cancellation of an invocation (this function)
|
||||||
|
ctx, cancelThisRun := context.WithCancel(ctx)
|
||||||
|
defer cancelThisRun()
|
||||||
|
runDone := make(chan struct{})
|
||||||
|
defer close(runDone)
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-runDone:
|
||||||
|
case <-reset.Wait(ctx):
|
||||||
|
log.Info("reset received, cancelling current invocation")
|
||||||
|
cancelThisRun()
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
client, err := j.clientFactory.NewClient()
|
client, err := j.clientFactory.NewClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("factory cannot instantiate streamrpc client")
|
log.WithError(err).Error("factory cannot instantiate streamrpc client")
|
||||||
|
35
daemon/job/reset/reset.go
Normal file
35
daemon/job/reset/reset.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package reset
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type contextKey int
|
||||||
|
|
||||||
|
const contextKeyReset contextKey = iota
|
||||||
|
|
||||||
|
func Wait(ctx context.Context) <-chan struct{} {
|
||||||
|
wc, ok := ctx.Value(contextKeyReset).(chan struct{})
|
||||||
|
if !ok {
|
||||||
|
wc = make(chan struct{})
|
||||||
|
}
|
||||||
|
return wc
|
||||||
|
}
|
||||||
|
|
||||||
|
type Func func() error
|
||||||
|
|
||||||
|
var AlreadyReset = errors.New("already reset")
|
||||||
|
|
||||||
|
func Context(ctx context.Context) (context.Context, Func) {
|
||||||
|
wc := make(chan struct{})
|
||||||
|
wuf := func() error {
|
||||||
|
select {
|
||||||
|
case wc <- struct{}{}:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return AlreadyReset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return context.WithValue(ctx, contextKeyReset, wc), wuf
|
||||||
|
}
|
10
main.go
10
main.go
@ -29,15 +29,15 @@ var daemonCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var wakeupCmd = &cobra.Command{
|
var signalCmd = &cobra.Command{
|
||||||
Use: "wakeup JOB",
|
Use: "signal [wakeup|reset] JOB",
|
||||||
Short: "trigger replication and subsequent pruning for a job",
|
Short: "wake up a job from wait state or abort its current invocation",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
conf, err := config.ParseConfig(rootArgs.configFile)
|
conf, err := config.ParseConfig(rootArgs.configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return client.RunWakeup(conf, args)
|
return client.RunSignal(conf, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ func init() {
|
|||||||
//cobra.OnInitialize(initConfig)
|
//cobra.OnInitialize(initConfig)
|
||||||
rootCmd.PersistentFlags().StringVar(&rootArgs.configFile, "config", "", "config file path")
|
rootCmd.PersistentFlags().StringVar(&rootArgs.configFile, "config", "", "config file path")
|
||||||
rootCmd.AddCommand(daemonCmd)
|
rootCmd.AddCommand(daemonCmd)
|
||||||
rootCmd.AddCommand(wakeupCmd)
|
rootCmd.AddCommand(signalCmd)
|
||||||
statusCmd.Flags().BoolVar(&statusCmdFlags.Raw, "raw", false, "dump raw status description from zrepl daemon")
|
statusCmd.Flags().BoolVar(&statusCmdFlags.Raw, "raw", false, "dump raw status description from zrepl daemon")
|
||||||
rootCmd.AddCommand(statusCmd)
|
rootCmd.AddCommand(statusCmd)
|
||||||
rootCmd.AddCommand(stdinserverCmd)
|
rootCmd.AddCommand(stdinserverCmd)
|
||||||
|
Loading…
Reference in New Issue
Block a user