Add leadership election
Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
parent
5a0440d6f8
commit
bea5ad3f13
7 changed files with 138 additions and 29 deletions
|
@ -1,6 +1,7 @@
|
|||
package safe
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
"log"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
|
@ -11,11 +12,44 @@ type routine struct {
|
|||
stop chan bool
|
||||
}
|
||||
|
||||
// Pool creates a pool of go routines
|
||||
type routineCtx func(ctx context.Context)
|
||||
|
||||
// Pool is a pool of go routines
|
||||
type Pool struct {
|
||||
routines []routine
|
||||
waitGroup sync.WaitGroup
|
||||
lock sync.Mutex
|
||||
routines []routine
|
||||
routinesCtx []routineCtx
|
||||
waitGroup sync.WaitGroup
|
||||
lock sync.Mutex
|
||||
baseCtx context.Context
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
// NewPool creates a Pool
|
||||
func NewPool(baseCtx context.Context) *Pool {
|
||||
ctx, cancel := context.WithCancel(baseCtx)
|
||||
return &Pool{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
baseCtx: baseCtx,
|
||||
}
|
||||
}
|
||||
|
||||
// Ctx returns main context
|
||||
func (p *Pool) Ctx() context.Context {
|
||||
return p.ctx
|
||||
}
|
||||
|
||||
//GoCtx starts a recoverable goroutine with a context
|
||||
func (p *Pool) GoCtx(goroutine routineCtx) {
|
||||
p.lock.Lock()
|
||||
p.routinesCtx = append(p.routinesCtx, goroutine)
|
||||
p.waitGroup.Add(1)
|
||||
Go(func() {
|
||||
goroutine(p.ctx)
|
||||
p.waitGroup.Done()
|
||||
})
|
||||
p.lock.Unlock()
|
||||
}
|
||||
|
||||
// Go starts a recoverable goroutine, and can be stopped with stop chan
|
||||
|
@ -37,6 +71,7 @@ func (p *Pool) Go(goroutine func(stop chan bool)) {
|
|||
// Stop stops all started routines, waiting for their termination
|
||||
func (p *Pool) Stop() {
|
||||
p.lock.Lock()
|
||||
p.cancel()
|
||||
for _, routine := range p.routines {
|
||||
routine.stop <- true
|
||||
}
|
||||
|
@ -47,6 +82,29 @@ func (p *Pool) Stop() {
|
|||
p.lock.Unlock()
|
||||
}
|
||||
|
||||
// Start starts all stoped routines
|
||||
func (p *Pool) Start() {
|
||||
p.lock.Lock()
|
||||
p.ctx, p.cancel = context.WithCancel(p.baseCtx)
|
||||
for _, routine := range p.routines {
|
||||
p.waitGroup.Add(1)
|
||||
routine.stop = make(chan bool, 1)
|
||||
Go(func() {
|
||||
routine.goroutine(routine.stop)
|
||||
p.waitGroup.Done()
|
||||
})
|
||||
}
|
||||
|
||||
for _, routine := range p.routinesCtx {
|
||||
p.waitGroup.Add(1)
|
||||
Go(func() {
|
||||
routine(p.ctx)
|
||||
p.waitGroup.Done()
|
||||
})
|
||||
}
|
||||
p.lock.Unlock()
|
||||
}
|
||||
|
||||
// Go starts a recoverable goroutine
|
||||
func Go(goroutine func()) {
|
||||
GoWithRecover(goroutine, defaultRecoverGoroutine)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue