mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: sync.WaitGroup replacement common.WaitGroup (#937)
* fn: sync.WaitGroup replacement common.WaitGroup agent/lb_agent/pure_runner has been incorrectly using sync.WaitGroup semantics. Switching these components to use the new common.WaitGroup() that provides a few handy functionality for common graceful shutdown cases. From https://golang.org/pkg/sync/#WaitGroup, "Note that calls with a positive delta that occur when the counter is zero must happen before a Wait. Calls with a negative delta, or calls with a positive delta that start when the counter is greater than zero, may happen at any time. Typically this means the calls to Add should execute before the statement creating the goroutine or other event to be waited for. If a WaitGroup is reused to wait for several independent sets of events, new Add calls must happen after all previous Wait calls have returned." HandleCallEnd introduces some complexity to the shutdowns, but this is currently handled by AddSession(2) initially and letting the HandleCallEnd() when to decrement by -1 in addition to decrement -1 in Submit(). lb_agent shutdown sequence and particularly timeouts with runner pool needs another look/revision, but this is outside of the scope of this commit. * fn: lb-agent wg share * fn: no need to +2 in Submit with defer. Removed defer since handleCallEnd already has this responsibility.
This commit is contained in:
@@ -12,8 +12,6 @@ import (
|
||||
)
|
||||
|
||||
func (a *agent) asyncDequeue() {
|
||||
defer a.wg.Done() // we can treat this thread like one big task and get safe shutdown fo free
|
||||
|
||||
// this is just so we can hang up the dequeue request if we get shut down
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
@@ -24,7 +22,8 @@ func (a *agent) asyncDequeue() {
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-a.shutdown:
|
||||
case <-a.shutWg.Closer():
|
||||
a.shutWg.AddSession(-1)
|
||||
return
|
||||
case <-a.resources.WaitAsyncResource(ctx):
|
||||
// TODO we _could_ return a token here to reserve the ram so that there's
|
||||
@@ -35,15 +34,20 @@ func (a *agent) asyncDequeue() {
|
||||
|
||||
// we think we can get a cookie now, so go get a cookie
|
||||
select {
|
||||
case <-a.shutdown:
|
||||
case <-a.shutWg.Closer():
|
||||
a.shutWg.AddSession(-1)
|
||||
return
|
||||
case model, ok := <-a.asyncChew(ctx):
|
||||
if ok {
|
||||
a.wg.Add(1) // need to add 1 in this thread to ensure safe shutdown
|
||||
go func(model *models.Call) {
|
||||
a.asyncRun(ctx, model)
|
||||
a.wg.Done() // can shed it after this is done, Submit will add 1 too but it's fine
|
||||
a.shutWg.AddSession(-1)
|
||||
}(model)
|
||||
|
||||
// WARNING: tricky. We reserve another session for next iteration of the loop
|
||||
if !a.shutWg.AddSession(1) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user