daemon/active: implement watchdog to handle stuck replication / pruners
ActiveSide.do() can only run sequentially, i.e. we cannot run replication and pruning in parallel. Why? * go-streamrpc only allows one active request at a time (this is bad design and should be fixed at some point) * replication and pruning are implemented independently, but work on the same resources (snapshots) A: pruning might destroy a snapshot that is planned to be replicated B: replication might replicate snapshots that should be pruned We do not have any resource management / locking for A and B, but we have a use case where users don't want their machine fill up with snapshots if replication does not work. That means we _have_ to run the pruners. A further complication is that we cannot just cancel the replication context after a timeout and move on to the pruner: it could be initial replication and we don't know how long it will take. (And we don't have resumable send & recv yet). With the previous commits, we can implement the watchdog using context cancellation. Note that the 'MadeProgress()' calls can only be placed right before non-error state transition. Otherwise, we could end up in a live-lock.
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/zrepl/zrepl/logger"
|
||||
"github.com/zrepl/zrepl/pruning"
|
||||
"github.com/zrepl/zrepl/replication/pdu"
|
||||
"github.com/zrepl/zrepl/util/watchdog"
|
||||
"net"
|
||||
"sort"
|
||||
"sync"
|
||||
@@ -56,6 +57,8 @@ type args struct {
|
||||
type Pruner struct {
|
||||
args args
|
||||
|
||||
Progress watchdog.KeepAlive
|
||||
|
||||
mtx sync.RWMutex
|
||||
|
||||
state State
|
||||
@@ -175,6 +178,10 @@ func (s State) statefunc() state {
|
||||
return statemap[s]
|
||||
}
|
||||
|
||||
func (s State) IsTerminal() bool {
|
||||
return s.statefunc() == nil
|
||||
}
|
||||
|
||||
type updater func(func(*Pruner)) State
|
||||
type state func(args *args, u updater) state
|
||||
|
||||
@@ -249,6 +256,12 @@ func (p *Pruner) Report() *Report {
|
||||
return &r
|
||||
}
|
||||
|
||||
func (p *Pruner) State() State {
|
||||
p.mtx.Lock()
|
||||
defer p.mtx.Unlock()
|
||||
return p.state
|
||||
}
|
||||
|
||||
type fs struct {
|
||||
path string
|
||||
|
||||
|
||||
Reference in New Issue
Block a user