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