snapshot_worker_state.go RawHistoryFolder
1package daemon
2
3import (
4 "context"
5 "sync"
6)
7
8// snapshotWorker owns the state of the repository snapshot worker and of the
9// other durable writers joined with it (maintenance and restoration), so
10// WaitDurableWriters can read all three completion signals under one lock.
11//
12// Lock position: mu is a leaf with respect to Daemon.mu. No code path acquires
13// Daemon.mu, a session lock, or a pane lock while holding it, and capture,
14// queue, and worker code never takes Daemon.mu. noticeMu is likewise a leaf and
15// is never held together with mu.
16//
17// The zero value is usable for tests that build &Daemon{}: nil maps are
18// allocated lazily by the enqueue paths, and a nil jobs channel never becomes
19// ready in a select.
20type snapshotWorker struct {
21 // jobs is the bounded regular capture queue. It is never closed: producers
22 // can race shutdown without risking a send-on-closed panic.
23 jobs chan *snapshotCapture
24 // wake wakes the repository scheduler when a session becomes dirty
25 // or an attempt completes. It is never closed and producers only send
26 // non-blockingly.
27 wake chan struct{}
28
29 // mu guards every field below it.
30 mu sync.Mutex
31 // admitted contains every capture accepted by either worker queue,
32 // including captures buffered in jobs.
33 admitted map[*snapshotCapture]struct{}
34 id uint64
35 ctx context.Context
36 cancel context.CancelFunc
37 done chan struct{}
38 flush chan struct{}
39 finalWake chan struct{}
40 // finalJobs coalesces terminal captures by session when the bounded
41 // regular queue is full. It retains at most snapshotFinalQueueCapacity named
42 // sessions, each with only its newest terminal state while the worker blocks.
43 finalJobs map[*session]*snapshotCapture
44 finalOrder []*session
45 closing bool
46 inFlight *snapshotCapture
47
48 // maintenanceWorkerCancel/Done and restoreWorkerDone are the other durable
49 // writers' ownership signals. They share mu with the snapshot worker and are
50 // joined together in WaitDurableWriters; never split them. Startup
51 // restoration reconciles durable checkpoints, so it is a durable writer.
52 maintenanceWorkerCancel context.CancelFunc
53 maintenanceWorkerDone chan struct{}
54 restoreWorkerDone chan struct{}
55
56 // noticeMu guards the active global persistence failure signature. It is
57 // separate from mu so notice routing cannot block a producer or a
58 // repository worker.
59 noticeMu sync.Mutex
60 activeFailureSignature string
61}