| 1 | package session |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "errors" |
| 6 | ) |
| 7 | |
| 8 | // CloseAll releases every runtime this service still owns. A runtime a client |
| 9 | // is still bound to is reported, not torn down underneath that client. |
| 10 | func (s *Service) CloseAll(ctx context.Context) error { |
| 11 | return s.closeAll(ctx, false) |
| 12 | } |
| 13 | |
| 14 | func (s *Service) closeAll(ctx context.Context, terminal bool) error { |
| 15 | if s == nil { |
| 16 | return nil |
| 17 | } |
| 18 | s.mu.Lock() |
| 19 | runtimes := make([]*Runtime, 0, len(s.active)) |
| 20 | for _, runtime := range s.active { |
| 21 | runtimes = append(runtimes, runtime) |
| 22 | } |
| 23 | s.mu.Unlock() |
| 24 | var closeErr error |
| 25 | for _, runtime := range runtimes { |
| 26 | closeErr = errors.Join(closeErr, s.closeRuntime(ctx, runtime, "", terminal)) |
| 27 | } |
| 28 | return closeErr |
| 29 | } |
| 30 | |
| 31 | // Shutdown closes execution ownership and the query projection workers that |
| 32 | // share this service's persistence root. CloseAll intentionally remains the |
| 33 | // runtime-only primitive; hosts and short-lived import services must use this |
| 34 | // lifecycle boundary before releasing or removing the root directory. |
| 35 | // |
| 36 | // Because callers rely on that guarantee, Shutdown is terminal: a runtime a |
| 37 | // client never unbound is still closed, so its writer lease and recovery |
| 38 | // handles are released instead of surviving until process exit. The leaked |
| 39 | // binding is reported rather than swallowed. |
| 40 | func (s *Service) Shutdown(ctx context.Context) error { |
| 41 | if s == nil { |
| 42 | return nil |
| 43 | } |
| 44 | // Stop and join cold-query workers before closing live runtimes. Otherwise |
| 45 | // a worker can open a recovery projection after CloseAll collected its |
| 46 | // runtime set and leave the Bolt handle behind during Windows cleanup. |
| 47 | s.query.Close() |
| 48 | return s.closeAll(ctx, true) |
| 49 | } |
| 50 |