Skip to content

Commit 7e48729

Browse files
authored
remove parentCtx from the httpserver Runnable (#48)
* remove parentCtx from the httpserver Runnable * use t.Context instead of context.Background for tests
1 parent dac0f2a commit 7e48729

15 files changed

+84
-132
lines changed

examples/http/main.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,27 +81,22 @@ func buildRoutes(logHandler slog.Handler) ([]httpserver.Route, error) {
8181
}
8282

8383
// RunServer initializes and runs the HTTP server with supervisor
84-
// Returns the supervisor and a cleanup function
8584
func RunServer(
8685
ctx context.Context,
8786
logHandler slog.Handler,
8887
routes []httpserver.Route,
89-
) (*supervisor.PIDZero, func(), error) {
88+
) (*supervisor.PIDZero, error) {
9089
// Create a config callback function that will be used by the runner
9190
configCallback := func() (*httpserver.Config, error) {
9291
return httpserver.NewConfig(ListenOn, routes, httpserver.WithDrainTimeout(DrainTimeout))
9392
}
9493

95-
// Create the HTTP server runner with a custom context
96-
customCtx, customCancel := context.WithCancel(ctx)
97-
94+
// Create the HTTP server runner
9895
runner, err := httpserver.NewRunner(
99-
httpserver.WithContext(customCtx),
10096
httpserver.WithConfigCallback(configCallback),
10197
httpserver.WithLogHandler(logHandler))
10298
if err != nil {
103-
customCancel()
104-
return nil, nil, fmt.Errorf("failed to create HTTP server runner: %w", err)
99+
return nil, fmt.Errorf("failed to create HTTP server runner: %w", err)
105100
}
106101

107102
// Create a PIDZero supervisor and add the runner
@@ -110,11 +105,10 @@ func RunServer(
110105
supervisor.WithLogHandler(logHandler),
111106
supervisor.WithRunnables(runner))
112107
if err != nil {
113-
customCancel()
114-
return nil, nil, fmt.Errorf("failed to create supervisor: %w", err)
108+
return nil, fmt.Errorf("failed to create supervisor: %w", err)
115109
}
116110

117-
return sv, customCancel, nil
111+
return sv, nil
118112
}
119113

120114
func main() {
@@ -135,12 +129,11 @@ func main() {
135129
os.Exit(1)
136130
}
137131

138-
sv, cancel, err := RunServer(ctx, handler, routes)
132+
sv, err := RunServer(ctx, handler, routes)
139133
if err != nil {
140134
slog.Error("Failed to setup server", "error", err)
141135
os.Exit(1)
142136
}
143-
defer cancel()
144137

145138
// Start the supervisor - this will block until shutdown
146139
slog.Info("Starting supervisor with HTTP server on " + ListenOn)

examples/http/main_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ func TestRunServer(t *testing.T) {
3030
require.NoError(t, err, "Failed to build routes")
3131
require.NotEmpty(t, routes, "Routes should not be empty")
3232

33-
sv, cleanup, err := RunServer(ctx, logHandler, routes)
33+
sv, err := RunServer(ctx, logHandler, routes)
3434
require.NoError(t, err, "RunServer should not return an error")
3535
require.NotNil(t, sv, "Supervisor should not be nil")
36-
require.NotNil(t, cleanup, "Cleanup function should not be nil")
3736

3837
// Start the server in a goroutine to avoid blocking the test
3938
errCh := make(chan error, 1)
@@ -54,8 +53,8 @@ func TestRunServer(t *testing.T) {
5453
assert.Equal(t, http.StatusOK, resp.StatusCode)
5554
assert.Equal(t, "Status: OK\n", string(body))
5655

57-
// Clean up
58-
cleanup()
56+
// Stop the supervisor
57+
sv.Shutdown()
5958

6059
// Check that Run() didn't return an error
6160
select {
@@ -88,7 +87,6 @@ func TestRunServerInvalidPort(t *testing.T) {
8887

8988
// Create HTTP server runner with invalid port
9089
runner, err := httpserver.NewRunner(
91-
httpserver.WithContext(ctx),
9290
httpserver.WithConfigCallback(configCallback),
9391
httpserver.WithLogHandler(logHandler.WithGroup("httpserver")),
9492
)

runnables/httpcluster/runner.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ func defaultRunnerFactory(
6363
return httpserver.NewRunner(
6464
httpserver.WithName(id),
6565
httpserver.WithConfig(cfg),
66-
httpserver.WithContext(ctx),
6766
httpserver.WithLogHandler(handler),
6867
)
6968
}

runnables/httpserver/config_test.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,10 @@ func TestContextPropagation(t *testing.T) {
298298
return NewConfig(listenPort, hConfig, WithDrainTimeout(2*time.Second))
299299
}
300300

301-
// Create a new context that we'll cancel to trigger shutdown
302-
ctx, cancel := context.WithCancel(context.Background())
303-
defer cancel()
301+
// Context for the server Run method
302+
ctx := t.Context()
304303

305304
server, err := NewRunner(
306-
WithContext(ctx),
307305
WithConfigCallback(cfgCallback),
308306
)
309307
require.NoError(t, err)
@@ -313,7 +311,7 @@ func TestContextPropagation(t *testing.T) {
313311

314312
// Start the server in a goroutine
315313
go func() {
316-
err := server.Run(context.Background())
314+
err := server.Run(ctx)
317315
runComplete <- err
318316
}()
319317

@@ -346,7 +344,7 @@ func TestContextPropagation(t *testing.T) {
346344
}
347345

348346
// Initiate server shutdown
349-
cancel() // This should cancel the context passed to the server
347+
server.Stop() // This should cancel the server's context
350348

351349
// Verify that the handler's context was canceled
352350
select {

runnables/httpserver/helpers_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package httpserver
22

33
import (
4-
"context"
54
"fmt"
65
"net"
76
"net/http"
@@ -44,7 +43,7 @@ func createTestServer(
4443
return NewConfig(listenPort, hConfig, WithDrainTimeout(drainTimeout))
4544
}
4645

47-
server, err := NewRunner(WithContext(context.Background()), WithConfigCallback(cfgCallback))
46+
server, err := NewRunner(WithConfigCallback(cfgCallback))
4847
require.NoError(t, err)
4948
require.NotNil(t, server)
5049

runnables/httpserver/options.go

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

33
import (
4-
"context"
54
"log/slog"
65
)
76

@@ -21,16 +20,6 @@ func WithLogHandler(handler slog.Handler) Option {
2120
}
2221
}
2322

24-
// WithContext sets a custom context for the Runner instance.
25-
// This allows for more granular control over cancellation and timeouts.
26-
func WithContext(ctx context.Context) Option {
27-
return func(r *Runner) {
28-
if ctx != nil {
29-
r.ctx, r.cancel = context.WithCancel(ctx)
30-
}
31-
}
32-
}
33-
3423
// WithConfigCallback sets the function that will be called to load or reload configuration.
3524
// Either this option or WithConfig initializes the Runner instance by providing the
3625
// configuration for the HTTP server managed by the Runner.

runnables/httpserver/options_test.go

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package httpserver
22

33
import (
4-
"context"
54
"log/slog"
65
"net/http"
76
"strings"
@@ -13,47 +12,6 @@ import (
1312
"github.com/stretchr/testify/require"
1413
)
1514

16-
// Define a custom type for context keys to avoid string collision
17-
type contextKey string
18-
19-
// TestWithContext verifies the WithContext option works correctly
20-
func TestWithContext(t *testing.T) {
21-
t.Parallel()
22-
// Create a custom context with a value using the type-safe key
23-
testKey := contextKey("test-key")
24-
customCtx := context.WithValue(context.Background(), testKey, "test-value")
25-
// Create a server with the custom context
26-
handler := func(w http.ResponseWriter, r *http.Request) {}
27-
route, err := NewRoute("v1", "/", handler)
28-
require.NoError(t, err)
29-
hConfig := Routes{*route}
30-
cfgCallback := func() (*Config, error) {
31-
return NewConfig(":0", hConfig, WithDrainTimeout(1*time.Second))
32-
}
33-
server, err := NewRunner(WithContext(context.Background()),
34-
WithConfigCallback(cfgCallback),
35-
WithContext(customCtx))
36-
require.NoError(t, err)
37-
// Verify the custom context was applied
38-
actualValue := server.ctx.Value(testKey)
39-
assert.Equal(t, "test-value", actualValue, "Context value should be preserved")
40-
// Verify cancellation works through server.Stop()
41-
done := make(chan struct{})
42-
go func() {
43-
<-server.ctx.Done()
44-
close(done)
45-
}()
46-
// Call Stop to cancel the internal context
47-
server.Stop()
48-
// Wait for the server context to be canceled or timeout
49-
select {
50-
case <-done:
51-
// Success, context was canceled
52-
case <-time.After(1 * time.Second):
53-
t.Fatal("Context cancellation not propagated")
54-
}
55-
}
56-
5715
func TestWithLogHandler(t *testing.T) {
5816
t.Parallel()
5917
// Create a custom logger with a buffer for testing output
@@ -69,7 +27,6 @@ func TestWithLogHandler(t *testing.T) {
6927
}
7028
// Create a server with the custom logger
7129
server, err := NewRunner(
72-
WithContext(context.Background()),
7330
WithConfigCallback(cfgCallback),
7431
WithLogHandler(customHandler),
7532
)
@@ -95,7 +52,6 @@ func TestWithConfig(t *testing.T) {
9552
require.NoError(t, err)
9653
// Create a server with the static config
9754
server, err := NewRunner(
98-
WithContext(context.Background()),
9955
WithConfig(staticConfig),
10056
)
10157
require.NoError(t, err)
@@ -143,7 +99,6 @@ func TestWithServerCreator(t *testing.T) {
14399
}
144100
// Create a server with the config that has a custom server creator
145101
server, err := NewRunner(
146-
WithContext(context.Background()),
147102
WithConfigCallback(cfgCallback),
148103
)
149104
require.NoError(t, err)

runnables/httpserver/reload_mocked_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package httpserver
22

33
import (
4-
"context"
54
"errors"
65
"net/http"
76
"testing"
@@ -203,7 +202,6 @@ func TestReloadConfig_WithFullRunner(t *testing.T) {
203202

204203
// Create the Runner with the config callback
205204
runner, err := NewRunner(
206-
WithContext(context.Background()),
207205
WithConfigCallback(configCallback),
208206
)
209207
require.NoError(t, err)

0 commit comments

Comments
 (0)