authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-03 21:25:41-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-03 21:43:41-07:00
loge555f7cca8a01b01a44cb5a6689d4e8f7072491a
treef194aacb8e619b9acd6e5c183c79bff3f7be68bf
parent724f7aa7062d2a561f051778a85ee35deb71ebf7
signature Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU

docs: clarify sync shutdown in the browser

Native stop waits for in-flight work; browser cancellation lets that work finish while it retains cache ownership. Remove comments that assumed every browser sync step was synchronous. Validation: cargo fmt and notebook doctests. Assisted-by: gpt-6.1-sol

3 files changed, 5 insertions(+), 9 deletions(-)

crates/notebook/src/background.rs+1-3
......@@ -508,13 +508,11 @@ impl Background {
508508 self.0.signal.wake();
509509 }
510510
511 /// Stops for good, waiting for the step in flight, so that no replica stays open and no
512 /// watch holds the notebook's folder.
511 /// Stops future checks; native threads finish the current step before returning.
513512 pub fn stop(&self) {
514513 self.0.signal.stopped.store(true, Ordering::Release);
515514 self.0.signal.wake();
516515 let thread = self.1.lock().ok().and_then(|mut thread| thread.take());
517 // In the browser no step is in flight while another task runs.
518516 #[cfg(not(target_arch = "wasm32"))]
519517 if let Some(thread) = thread {
520518 let _ = thread.join();
crates/notebook/src/session.rs+2-3
......@@ -2390,9 +2390,8 @@ impl Section {
23902390 &self.replica
23912391 }
23922392
2393 /// Waits for the in-flight operation and callback before releasing the replica.
2394 /// Dropping instead requests cancellation without waiting; the worker retains
2395 /// cache ownership until that operation finishes. Remote calls must be bounded.
2393 /// Stops future sync steps; native threads finish the current operation before returning.
2394 /// The worker retains cache ownership until its in-flight operation finishes.
23962395 pub fn close(mut self) -> Result<()> {
23972396 match self.worker.take() {
23982397 Some(worker) => worker.stop(),
crates/notebook/src/worker.rs+2-3
......@@ -79,7 +79,7 @@ impl Signal {
7979}
8080
8181/// Owns automatic reconciliation. Dropping requests cancellation without blocking.
82/// The in-flight sync step finishes before ownership is released; `stop` waits for it.
82/// The in-flight sync step retains cache ownership until it finishes.
8383pub struct SyncWorker {
8484 signal: Arc<Signal>,
8585 thread: Option<JoinHandle<Result<()>>>,
......@@ -116,14 +116,13 @@ impl SyncWorker {
116116 self.signal.wake();
117117 }
118118
119 /// Cancels future steps and waits for the current step and callback to finish.
119 /// Cancels future steps; native threads finish the current step and callback before returning.
120120 /// A stopped worker leaves pending edits and uncertain attempts in the cache.
121121 /// Call outside the worker's own callback, which cannot join its calling thread.
122122 pub fn stop(mut self) -> Result<()> {
123123 self.signal.stopped.store(true, Ordering::Release);
124124 self.signal.wake();
125125 let thread = self.thread.take().expect("Worker owns its thread");
126 // In the browser no step is in flight outside the worker's own callback.
127126 #[cfg(target_arch = "wasm32")]
128127 return thread.finished().unwrap_or(Ok(()));
129128 #[cfg(not(target_arch = "wasm32"))]