mirror of
https://github.com/logseq/logseq.git
synced 2026-05-01 09:26:28 +00:00
1.9 KiB
1.9 KiB
This document describes the handling of cycles formed between multiple blocks in the implementation of db-sync.
When cycles are detected
- Cycles are detected on the server when applying client tx batches in
deps/db-sync/src/logseq/db_sync/worker.cljs. - The server calls
logseq.db-sync.cycle/detect-cyclewhich inspects updates to:block/parent(and other special attrs like class extends). - If applying the tx would introduce a cycle, the server rejects the batch with
{:type "tx/reject" :reason "cycle" ...}.
What the server returns
- The reject payload includes:
attr: the attribute that introduced the cycle (for blocks this is:block/parent).server_values: a map of the affected entities to the server’s current value forattr(fromlogseq.db-sync.cycle/server-values-for).
- This allows the client to realign its local state to the server’s authoritative values.
Client-side reconciliation
- The client handles
tx/rejectwith reason"cycle"insrc/main/frontend/worker/db_sync.cljs. - It calls
reconcile-cycle!which builds:db/add/:db/retractops to restoreattrto the server values, then transacts them locally with:rtc-tx? true. - The intent is to correct local cycles and prevent re-uploading conflicting changes.
- The client also strips cycle-related attrs (
:block/parent,:logseq.property.class/extends) from the rejected inflight txs, requeues the remaining changes, and flushes pending txs so other attribute updates still sync. - TODO: During
pull/ok, after applying remote txs, the client checks cycle-related attrs touched by the tx. If a cycle is detected:- For
:block/parent, reparent the affected block to its page root (top-level) and persist the op so it is uploaded to the server. - For other cycle attrs (e.g.
:logseq.property.class/extends), retract the attr locally.
- For
Known pitfalls and fixes
- :logseq.property.class/extends not well handled yet, let it be for now, FIX it later