Overview
| Artifact ID: | 70570bdcd69a6eed7c8ae6b2eb3aa2abe4cc63cf7fb7e6592ad95cace669d520 |
|---|---|
| Page Name: | index |
| Date: | 2026-10-13 02:27:53 |
| Original User: | dmestas |
| Mimetype: | text/x-markdown |
Content
EdgeSync
Distributed Fossil repository synchronization over NATS. Replace Fossil's HTTP sync on leaf nodes with NATS messaging — the master Fossil server stays untouched.
Architecture
right
R1: cylinder "repo" color white fill 0x3a3a3a width 0.7 height 0.5 rad 3px
move 0.3
LA: box "Leaf Agent" color white fill 0x2a6b3a width 1.3 height 0.5 rad 5px
move 0.3
N: cylinder "NATS" color white fill 0x2a4a6b width 0.8 height 0.6 rad 5px
move 0.3
BR: box "Bridge" color white fill 0x6b5a2a width 1.0 height 0.5 rad 5px
move 0.3
FS: box "Fossil Server" color white fill 0x6b2a2a width 1.4 height 0.5 rad 5px
move 0.3
R2: cylinder "master" color white fill 0x3a3a3a width 0.7 height 0.5 rad 3px
arrow from R1.e to LA.w color white thick
arrow from LA.e to N.w color white thick
arrow from N.e to BR.w color white thick
arrow from BR.e to FS.w color white thick
arrow from FS.e to R2.w color white thick
→ /pikchrshowEvery sync round is bidirectional — the leaf pushes local artifacts AND pulls remote changes in the same request/reply exchange. Data flows both directions through NATS and the bridge.
How It Works
- Developer A does
fossil commiton Leaf A — repo SQLite updated - Leaf A's agent polls (every 5s), detects new artifacts
- Leaf A syncs over NATS: sends what it has, asks for what it's missing
- Bridge forwards to Fossil server via HTTP, relays response back
- Leaf B polls, syncs, gets Developer A's changes from the server
- All leaves converge through the Fossil server as source of truth
The Fossil server never knows NATS exists. It just sees normal HTTP /xfer traffic.
Components
Leaf Agent
A Go daemon that sits next to a Fossil repo and keeps it synced.
right
R: cylinder "repo" color white fill 0x3a3a3a width 0.7 height 0.5 rad 3px
move 0.3
A: box "Leaf Agent" color white fill 0x2a6b3a width 1.3 height 0.5 rad 5px
move 0.3
N: cylinder "NATS" color white fill 0x2a4a6b width 0.8 height 0.5 rad 5px
arrow from R.e to A.w color white thick
arrow from A.e to N.w color white thick
→ /pikchrshow- Polls repo every 5s for new artifacts (configurable)
- Push AND pull in each sync round
SIGUSR1for immediate sync,SIGINT/SIGTERMfor shutdown
leaf-agent --repo /path/to/repo.fossil --nats nats://localhost:4222
Bridge
A proxy that translates NATS to Fossil's HTTP protocol.
right
N: cylinder "NATS" color white fill 0x2a4a6b width 0.8 height 0.5 rad 5px
move 0.3
B: box "Bridge" color white fill 0x6b5a2a width 1.0 height 0.5 rad 5px
move 0.3
F: box "Fossil Server" color white fill 0x6b2a2a width 1.4 height 0.5 rad 5px
arrow from N.e to B.w color white thick
arrow from B.e to F.w color white thick
→ /pikchrshow- Subscribes to NATS, forwards to Fossil server via HTTP
- Returns empty response on errors (never leaves the leaf hanging)
bridge --fossil http://fossil:8080 --project <project-code>
Multi-Leaf Sync
down
A: box "Leaf A" color white fill 0x2a6b3a width 0.9 height 0.35 rad 5px
move 0.15
B: box "Leaf B" color white fill 0x2a6b3a width 0.9 height 0.35 rad 5px
move 0.15
C: box "Leaf C" color white fill 0x2a6b3a width 0.9 height 0.35 rad 5px
N: cylinder "NATS" color white fill 0x2a4a6b width 0.8 height 0.5 rad 5px \
at 1.5 right of B
BR: box "Bridge" color white fill 0x6b5a2a width 0.9 height 0.35 rad 5px \
at 1.5 right of N
FS: box "Fossil" color white fill 0x6b2a2a width 0.9 height 0.35 rad 5px \
at 1.5 right of BR
arrow from A.e to N.nw color white
arrow from B.e to N.w color white thick
arrow from C.e to N.sw color white
arrow from N.e to BR.w color white thick
arrow from BR.e to FS.w color white thick
→ /pikchrshowLeaf A pushes changes. Leaf B and C pull them on their next sync cycle. All leaves converge through the Fossil server.
NATS Subject Scheme
<prefix>.<project-code>.sync
Default prefix: fossil. Configurable via --prefix.
Design Principles
- Master stays vanilla — no patches to Fossil
- Transport-agnostic —
sync.Transportinterface accepts any transport - Repo format preserved —
fossil uiworks on any synced repo - NATS WebSocket — browser leaves connect via
wss://
Built With
- go-libfossil — Pure Go Fossil library (12 packages)
- NATS — Messaging transport
- Go 1.25.4
Clone
fossil clone https://fossil.craftdesign.group/edgesync edgesync.fossil