plumb ctx for container removal spanno (#750)

these were just dangling off on the side, took some plumbing work but not so
bad
This commit is contained in:
Reed Allman
2018-02-08 22:48:23 -08:00
committed by Tolga Ceylan
parent c36c627b93
commit 27179ddf54
3 changed files with 24 additions and 22 deletions

View File

@@ -248,7 +248,7 @@ func (a *agent) submit(ctx context.Context, call *call) error {
return transformTimeout(err, true) return transformTimeout(err, true)
} }
defer slot.Close() // notify our slot is free once we're done defer slot.Close(ctx) // notify our slot is free once we're done
err = call.Start(ctx) err = call.Start(ctx)
if err != nil { if err != nil {
@@ -447,7 +447,7 @@ func (a *agent) waitHot(ctx context.Context, call *call) (Slot, error) {
case s := <-ch: case s := <-ch:
if s.acquireSlot() { if s.acquireSlot() {
if s.slot.Error() != nil { if s.slot.Error() != nil {
s.slot.Close() s.slot.Close(ctx)
return nil, s.slot.Error() return nil, s.slot.Error()
} }
return s.slot, nil return s.slot, nil
@@ -493,7 +493,7 @@ func (a *agent) launchCold(ctx context.Context, call *call) (Slot, error) {
select { select {
case s := <-ch: case s := <-ch:
if s.Error() != nil { if s.Error() != nil {
s.Close() s.Close(ctx)
return nil, s.Error() return nil, s.Error()
} }
return s, nil return s, nil
@@ -537,11 +537,13 @@ func (s *coldSlot) exec(ctx context.Context, call *call) error {
return ctx.Err() return ctx.Err()
} }
func (s *coldSlot) Close() error { func (s *coldSlot) Close(ctx context.Context) error {
if s.cookie != nil { if s.cookie != nil {
// call this from here so that in exec we don't have to eat container // call this from here so that in exec we don't have to eat container
// removal latency // removal latency
s.cookie.Close(context.Background()) // ensure container removal, separate ctx // NOTE ensure container removal, no ctx timeout
ctx = opentracing.ContextWithSpan(context.Background(), opentracing.SpanFromContext(ctx))
s.cookie.Close(ctx)
} }
if s.tok != nil { if s.tok != nil {
s.tok.Close() s.tok.Close()
@@ -557,7 +559,7 @@ type hotSlot struct {
err error err error
} }
func (s *hotSlot) Close() error { func (s *hotSlot) Close(ctx context.Context) error {
close(s.done) close(s.done)
return nil return nil
} }
@@ -643,7 +645,7 @@ func (a *agent) prepCold(ctx context.Context, call *call, tok ResourceToken, ch
select { select {
case ch <- slot: case ch <- slot:
case <-ctx.Done(): case <-ctx.Done():
slot.Close() slot.Close(ctx)
} }
} }
@@ -689,7 +691,7 @@ func (a *agent) runHot(ctx context.Context, call *call, tok ResourceToken, state
call.slots.queueSlot(&hotSlot{done: make(chan struct{}), err: err}) call.slots.queueSlot(&hotSlot{done: make(chan struct{}), err: err})
return return
} }
defer cookie.Close(context.Background()) // ensure container removal, separate ctx defer cookie.Close(ctx) // NOTE ensure this ctx doesn't time out
waiter, err := cookie.Run(ctx) waiter, err := cookie.Run(ctx)
if err != nil { if err != nil {
@@ -768,7 +770,7 @@ func (a *agent) runHot(ctx context.Context, call *call, tok ResourceToken, state
// if we can eject token, that means we are here due to // if we can eject token, that means we are here due to
// abort/shutdown/timeout, attempt to eject and terminate, // abort/shutdown/timeout, attempt to eject and terminate,
// otherwise continue processing the request // otherwise continue processing the request
if call.slots.ejectSlot(s) { if call.slots.ejectSlot(ctx, s) {
return return
} }

View File

@@ -17,7 +17,7 @@ import (
type Slot interface { type Slot interface {
exec(ctx context.Context, call *call) error exec(ctx context.Context, call *call) error
Close() error Close(ctx context.Context) error
Error() error Error() error
} }
@@ -81,7 +81,7 @@ func (a *slotToken) acquireSlot() bool {
return true return true
} }
func (a *slotQueue) ejectSlot(s *slotToken) bool { func (a *slotQueue) ejectSlot(ctx context.Context, s *slotToken) bool {
// let's get the lock // let's get the lock
if !atomic.CompareAndSwapUint32(&s.isBusy, 0, 1) { if !atomic.CompareAndSwapUint32(&s.isBusy, 0, 1) {
return false return false
@@ -96,7 +96,7 @@ func (a *slotQueue) ejectSlot(s *slotToken) bool {
} }
a.cond.L.Unlock() a.cond.L.Unlock()
s.slot.Close() s.slot.Close(ctx)
// now we have the lock, push the trigger // now we have the lock, push the trigger
close(s.trigger) close(s.trigger)
return true return true
@@ -142,7 +142,7 @@ func (a *slotQueue) startDequeuer(ctx context.Context) chan *slotToken {
case <-ctx.Done(): // time out or cancel from caller case <-ctx.Done(): // time out or cancel from caller
// consume slot, we let the hot container queue the slot again // consume slot, we let the hot container queue the slot again
if item.acquireSlot() { if item.acquireSlot() {
item.slot.Close() item.slot.Close(ctx)
} }
} }
} }

View File

@@ -18,7 +18,7 @@ func (a *testSlot) exec(ctx context.Context, call *call) error {
return nil return nil
} }
func (a *testSlot) Close() error { func (a *testSlot) Close(ctx context.Context) error {
if a.isClosed { if a.isClosed {
panic(fmt.Errorf("id=%d already closed %v", a.id, a)) panic(fmt.Errorf("id=%d already closed %v", a.id, a))
} }
@@ -77,19 +77,19 @@ func TestSlotQueueBasic1(t *testing.T) {
// Now according to LIFO semantics, we should get 9,8,7,6,5,4,3,2,1,0 if we dequeued right now. // Now according to LIFO semantics, we should get 9,8,7,6,5,4,3,2,1,0 if we dequeued right now.
// but let's eject 9 // but let's eject 9
if !obj.ejectSlot(tokens[9]) { if !obj.ejectSlot(ctx, tokens[9]) {
t.Fatalf("Cannot eject slotToken: %#v", tokens[9]) t.Fatalf("Cannot eject slotToken: %#v", tokens[9])
} }
// let eject 0 // let eject 0
if !obj.ejectSlot(tokens[0]) { if !obj.ejectSlot(ctx, tokens[0]) {
t.Fatalf("Cannot eject slotToken: %#v", tokens[0]) t.Fatalf("Cannot eject slotToken: %#v", tokens[0])
} }
// let eject 5 // let eject 5
if !obj.ejectSlot(tokens[5]) { if !obj.ejectSlot(ctx, tokens[5]) {
t.Fatalf("Cannot eject slotToken: %#v", tokens[5]) t.Fatalf("Cannot eject slotToken: %#v", tokens[5])
} }
// try ejecting 5 again, it should fail // try ejecting 5 again, it should fail
if obj.ejectSlot(tokens[5]) { if obj.ejectSlot(ctx, tokens[5]) {
t.Fatalf("Shouldn't be able to eject slotToken: %#v", tokens[5]) t.Fatalf("Shouldn't be able to eject slotToken: %#v", tokens[5])
} }
@@ -112,7 +112,7 @@ func TestSlotQueueBasic1(t *testing.T) {
t.Fatalf("Should not be able to acquire twice slotToken: %#v", z) t.Fatalf("Should not be able to acquire twice slotToken: %#v", z)
} }
z.slot.Close() z.slot.Close(ctx)
case <-time.After(time.Duration(1) * time.Second): case <-time.After(time.Duration(1) * time.Second):
t.Fatal("timeout in waiting slotToken") t.Fatal("timeout in waiting slotToken")
@@ -126,7 +126,7 @@ func TestSlotQueueBasic1(t *testing.T) {
} }
// eject it before we can consume // eject it before we can consume
if !obj.ejectSlot(tokens[7]) { if !obj.ejectSlot(ctx, tokens[7]) {
t.Fatalf("Cannot eject slotToken: %#v", tokens[2]) t.Fatalf("Cannot eject slotToken: %#v", tokens[2])
} }
@@ -263,14 +263,14 @@ func TestSlotQueueBasic3(t *testing.T) {
t.Fatalf("2 acquire should not fail") t.Fatalf("2 acquire should not fail")
} }
item.slot.Close() item.slot.Close(ctx)
case <-time.After(time.Duration(1) * time.Second): case <-time.After(time.Duration(1) * time.Second):
t.Fatal("timeout in waiting slotToken") t.Fatal("timeout in waiting slotToken")
} }
// let's eject 1 // let's eject 1
if !obj.ejectSlot(token1) { if !obj.ejectSlot(ctx, token1) {
t.Fatalf("failed to eject 1") t.Fatalf("failed to eject 1")
} }
if !slot1.(*testSlot).isClosed { if !slot1.(*testSlot).isClosed {