Skip to content

Commit e00ab88

Browse files
Merge pull request #32 from did-method-plc/DavidBuchanan314/hang-fix
replica: Fix context handling and replica shutdown
2 parents 9e8a0fd + bf9f347 commit e00ab88

3 files changed

Lines changed: 31 additions & 6 deletions

File tree

cmd/plc-replica/main.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,24 @@ func run(ctx context.Context, cmd *cli.Command) error {
137137
server := replica.NewServer(store, state, httpAddr, logger)
138138
g, gctx := errgroup.WithContext(ctx)
139139

140-
g.Go(server.Run)
140+
g.Go(func() error {
141+
return server.Run(gctx)
142+
})
141143

142144
g.Go(func() error {
143145
mux := http.NewServeMux()
144146
mux.Handle("/metrics", promhttp.Handler())
147+
srv := &http.Server{Addr: metricsAddr, Handler: mux}
148+
go func() {
149+
<-gctx.Done()
150+
srv.Shutdown(context.Background())
151+
}()
145152
slog.Info("metrics server listening", "addr", metricsAddr)
146-
return http.ListenAndServe(metricsAddr, mux)
153+
err := srv.ListenAndServe()
154+
if err == http.ErrServerClosed {
155+
return nil
156+
}
157+
return err
147158
})
148159

149160
if !noIngest {

replica/ingest.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,10 @@ func (i *Ingestor) Run(ctx context.Context) error {
196196
}()
197197

198198
// Start ingestion state machine in a goroutine
199-
go i.ingestLoop(ctx, &cursor, ingestedOps)
199+
go func() {
200+
i.ingestLoop(ctx, &cursor, ingestedOps)
201+
close(ingestedOps)
202+
}()
200203

201204
// Process operations from ingestion channel and add to InFlight before sending to workers
202205
for seqop := range ingestedOps {

replica/server.go

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

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"log/slog"
@@ -54,8 +55,8 @@ func NewServer(store *GormOpStore, state *ReplicaState, addr string, logger *slo
5455
}
5556
}
5657

57-
// Run starts the HTTP server (blocking)
58-
func (s *Server) Run() error {
58+
// Run starts the HTTP server (blocking). It shuts down gracefully when ctx is cancelled.
59+
func (s *Server) Run(ctx context.Context) error {
5960
mux := http.NewServeMux()
6061
mux.HandleFunc("GET /_health", s.handleHealth)
6162
mux.HandleFunc("GET /{did}/log/audit", s.handleDIDLogAudit)
@@ -67,8 +68,18 @@ func (s *Server) Run() error {
6768

6869
handler := otelhttp.NewHandler(mux, "")
6970

71+
srv := &http.Server{Addr: s.addr, Handler: handler}
72+
go func() {
73+
<-ctx.Done()
74+
srv.Shutdown(context.Background())
75+
}()
76+
7077
s.logger.Info("http server listening", "addr", s.addr)
71-
return http.ListenAndServe(s.addr, handler)
78+
err := srv.ListenAndServe()
79+
if err == http.ErrServerClosed {
80+
return nil
81+
}
82+
return err
7283
}
7384

7485
// handleIndex serves the index page

0 commit comments

Comments
 (0)