MCPcopy Create free account
hub / github.com/PerpetualSoftware/pad / Stop

Method Stop

internal/server/server.go:313–351  ·  view source on GitHub ↗

Stop waits for all background goroutines started via goAsync to finish AND drains the rate-limiter cleanup goroutines spawned at construction time (BUG-851). Safe to call multiple times. Should be called before Store.Close() so in-flight DB writes don't race a closed connection (or worse, the SQLite

()

Source from the content-addressed store, hash-verified

311// Store.Close() so in-flight DB writes don't race a closed connection
312// (or worse, the SQLite -wal/-shm file removal in t.TempDir cleanup).
313func (s *Server) Stop() {
314 // Signal long-running background loops (orphan GC, etc.) to exit.
315 // Each loop registers itself on s.bg, so the Wait() below blocks
316 // until they actually finish and any in-flight goroutines drain.
317 s.stopOrphanGC()
318 // Yjs op-log prune sweeper (TASK-1309). Same lifecycle pattern;
319 // signals BEFORE Wait() so the goroutine sees the close and exits.
320 s.stopOpLogGC()
321 // Short-lived-credential reaper (PLAN-1933 DR-5 / TASK-1936). Same
322 // lifecycle pattern; signal BEFORE Wait() so the goroutine exits.
323 s.stopTokenReaper()
324 // Soft-deleted-workspace hard-purge sweeper (TASK-1966). Same
325 // lifecycle pattern; signal BEFORE Wait() so the goroutine exits.
326 s.stopWorkspacePurgeSweeper()
327 // MCP audit writer / sweeper run on s.bg too. Signal first so
328 // the workers see the close BEFORE Wait() blocks; without the
329 // signal Wait would hang forever on the writer's blocking
330 // queue receive.
331 s.stopMCPAuditWriter()
332 // MCP session tracker (TASK-1120) runs its sweeper on s.bg too.
333 // Order with the audit writer doesn't matter — both are
334 // independent goroutines; we just need the close BEFORE Wait().
335 s.stopMCPSessionTracker()
336 // Close the collab room manager BEFORE bg.Wait() so any in-flight
337 // op-log GC sweep (TASK-1309) blocked on a per-item lock behind
338 // an active Join can drain. collab.Close() tears down the Joins
339 // (their WS readLoops return, runConn unwinds, itemLocks
340 // release), which unblocks the GC's per-item PruneItemOpLogIfDormantBefore
341 // call. Without this ordering, Stop() can deadlock: GC waits on
342 // itemLock; Join holds itemLock until WS closes; WS only closes
343 // when collab.Close() runs; collab.Close() only runs after
344 // bg.Wait(); bg.Wait() never returns because GC is stuck.
345 // Per Codex review of TASK-1309 [P2]. nil-safe: collab is optional.
346 if s.collab != nil {
347 s.collab.Close()
348 }
349 s.bg.Wait()
350 s.rateLimiters.Stop() // nil-safe via the RateLimiters receiver guard
351}
352
353func New(s *store.Store) *Server {
354 rl := NewRateLimiters()

Callers 15

startWALCheckpointerMethod · 0.45
pollUntilSetupDoneFunction · 0.45
RunStdioMethod · 0.45
newPadServerFunction · 0.45
runMethod · 0.45
testServerFunction · 0.45
testServerPostgresFunction · 0.45

Calls 7

stopOrphanGCMethod · 0.95
stopOpLogGCMethod · 0.95
stopTokenReaperMethod · 0.95
stopMCPAuditWriterMethod · 0.95
stopMCPSessionTrackerMethod · 0.95
CloseMethod · 0.65