Skip to content

Commit c3458e1

Browse files
author
Ben Reed
committed
Use a context parameter in (*Controller).Stop
The Stop method of the orch.Controller type accepted a time.Duration. It would wait for a graceful shutdown for this amount of time. Then, it would return an error if the graceful shutdown did not occur. This commit replaces the time.Duration with a context.Context, permitting more flexibility.
1 parent b10547b commit c3458e1

File tree

4 files changed

+27
-13
lines changed

4 files changed

+27
-13
lines changed

testctrl/cmd/orchtest/main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package main
1616

1717
import (
18+
"context"
1819
"flag"
1920
"log"
2021
"os"
@@ -53,7 +54,10 @@ func main() {
5354
if err := c.Start(); err != nil {
5455
panic(err)
5556
}
56-
defer c.Stop(*timeout)
57+
58+
shutdownCtx, cancel := context.WithTimeout(context.Background(), *timeout)
59+
defer cancel()
60+
defer c.Stop(shutdownCtx)
5761

5862
go func() {
5963
for i := 0; i < *count; i++ {

testctrl/cmd/svc/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package main
1616

1717
import (
18+
"context"
1819
"flag"
1920
"fmt"
2021
"net"
@@ -92,7 +93,9 @@ func main() {
9293
glog.Fatalf("unable to start orchestration controller: %v", err)
9394
}
9495

95-
defer controller.Stop(*shutdownTimeout)
96+
shutdownCtx, cancel := context.WithTimeout(context.Background(), *shutdownTimeout)
97+
defer cancel()
98+
defer controller.Stop(shutdownCtx)
9699

97100
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
98101
if err != nil {

testctrl/svc/orch/controller.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package orch
1616

1717
import (
18+
"context"
1819
"errors"
1920
"fmt"
2021
"sync"
@@ -158,15 +159,16 @@ func (c *Controller) Start() error {
158159
return nil
159160
}
160161

161-
// Stop attempts to terminate all orchestration threads spawned by a call to Start. It waits for a
162-
// graceful shutdown until for a specified timeout.
162+
// Stop attempts to terminate all orchestration threads spawned by a call to
163+
// Start. It waits for a graceful shutdown until the context is cancelled.
163164
//
164-
// If the timeout is reached before shutdown, an improper shutdown will occur. This may result in
165-
// unpredictable states for running sessions and their resources. To signal these potential issues,
166-
// an error is returned when this occurs.
165+
// If the context is cancelled before a graceful shutdown, an error is returned.
166+
// This improper shutdown may result in unpredictable states. It should be
167+
// avoided if possible.
167168
//
168-
// If Start was not called prior to Stop, there will be no adverse effects and nil will be returned.
169-
func (c *Controller) Stop(timeout time.Duration) error {
169+
// If Start was not called prior to Stop, there will be no adverse effects and
170+
// nil will be returned.
171+
func (c *Controller) Stop(ctx context.Context) error {
170172
defer c.watcher.Stop()
171173

172174
c.mux.Lock()
@@ -182,7 +184,7 @@ func (c *Controller) Stop(timeout time.Duration) error {
182184
select {
183185
case <-done:
184186
glog.Infof("controller: executors safely exited")
185-
case <-time.After(timeout):
187+
case <-ctx.Done():
186188
glog.Warning("controller: unable to wait for executors to safely exit, timed out")
187189
return fmt.Errorf("executors did not safely exit before timeout")
188190
}

testctrl/svc/orch/controller_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package orch
22

33
import (
4+
"context"
45
"errors"
56
"testing"
67
"time"
@@ -58,7 +59,7 @@ func TestControllerSchedule(t *testing.T) {
5859

5960
if tc.start {
6061
controller.Start()
61-
defer controller.Stop(0)
62+
defer controller.Stop(context.TODO())
6263
}
6364

6465
err := controller.Schedule(tc.session)
@@ -86,7 +87,7 @@ func TestControllerStart(t *testing.T) {
8687
t.Run("sets running state", func(t *testing.T) {
8788
controller, _ := NewController(fake.NewSimpleClientset(), nil, nil)
8889
controller.Start()
89-
defer controller.Stop(0)
90+
defer controller.Stop(context.TODO())
9091
if controller.Stopped() {
9192
t.Errorf("Stopped unexpectedly returned true after starting controller")
9293
}
@@ -196,7 +197,11 @@ func TestControllerStop(t *testing.T) {
196197

197198
go controller.loop()
198199
time.Sleep(timeout)
199-
err := controller.Stop(tc.stopTimeout)
200+
201+
ctx, cancel := context.WithTimeout(context.TODO(), tc.stopTimeout)
202+
defer cancel()
203+
204+
err := controller.Stop(ctx)
200205
if tc.shouldError && err == nil {
201206
t.Errorf("executors unexpectedly finished before timeout")
202207
} else if !tc.shouldError && err != nil {

0 commit comments

Comments
 (0)