Paint in Sync: A Gossip Canvas
A software-only way to see a peer-to-peer overlay actually work: a shared pixel canvas with no server. Paint a cell in your browser and watch it spread to every peer by gossip; because each cell is last-writer-wins, all nodes converge to the identical image no matter what order the updates arrive in. It's a hands-on look at the same membership and broadcast building blocks our platform runs on — and a starting point for your own distributed-systems prototypes in Java.
Who it's for
This demo is for students, researchers, and engineers who want to understand — and start building — peer-to-peer and decentralized systems, without first hand-rolling sockets, membership, failure detection, and message dissemination. You write ordinary Java; Babel gives you protocols, events, and timers as clean composition units, and this canvas wires real overlay protocols together end-to-end so you can read, run, and modify them.
It's a companion to our Babel P2P chat: where the chat uses the simplest possible membership and flood, this one steps up to the real overlay stack — partial-view membership and eager-push gossip — so it doubles as a working showcase of those protocols and a way to watch dissemination and convergence happen in front of you.
Read it, run it, fork it, and build your own application on top. If that's you, we'd love to hear what you make.
What it is
A collaborative pixel canvas — a tiny r/place — built from real Babel overlay protocols. There is no central server: every participant runs the same program, the nodes form a peer mesh, and each paint operation is gossiped across it. Every node applies operations last-writer-wins per cell, so any two nodes that have seen the same operations hold the identical image — convergence is purely a matter of the gossip reaching everyone, which is exactly what makes the canvas a clear, watchable demonstration of dissemination.
What it shows — and why it matters
Behind the pixels, the demo makes a few properties of decentralized systems tangible — the reasons this kind of overlay is worth building on:
- No server, no single point of failure. Every node is equal; there is nothing in the middle to provision, scale, or bring the whole thing down.
- It scales because nobody needs to know everyone. HyParView gives each node only a small partial view of the system — a handful of neighbours — yet those views stitch together into one connected overlay. The state and connections each node maintains stay small as the system grows.
- It heals itself. As nodes join, leave, or crash, the overlay repairs its views on its own — you can stop a node and watch the canvas keep flowing.
- Dissemination is robust, not fragile. Gossip spreads each update along several paths at once, so it still reaches everyone when links are slow or messages are dropped — at the cost of a little redundancy, which the protocol de-duplicates.
- Everyone ends up agreeing. Last-writer-wins per cell makes the canvas converge to the same image on every node regardless of the order updates arrive in — eventual consistency you can literally see.
These are the same properties ParadigmShift's platform relies on to build robust, self-managed, decentralized systems — here distilled into something you can open in a browser and poke at.
What it looks like
Each node serves a small web UI: the shared canvas, a colour palette, and a side panel listing this node's current overlay neighbours. Paint a cell on one node and it appears on all of them within a gossip round. On startup each node prints exactly how it bound and how it will find peers:
babel-canvas
network : en0 → 192.168.1.20 (auto-detected sole interface en0)
membership : 192.168.1.20:6000 (HyParView, TCP)
gossip : 192.168.1.20:6001 (offset +1)
web UI : http://localhost:8000/
discovery : multicast 233.138.122.123
bootstrap : auto-discovery — probe the LAN and connect to whoever answers
Convergence is observable, not just asserted: every node periodically reports a digest of its canvas, and once gossip settles the digests match across the mesh — the same signal our validation harness checks automatically.
How it works
The cooperating layers — the real overlay stack our platform builds on, with the canvas on top:
- Membership — HyParView. A partial-view membership protocol: each node keeps a small active view (its gossip neighbours) and a larger passive view of fallback peers, using random walks to propagate joins and periodic shuffles to refresh the passive view. The result is a connected, self-healing overlay that survives churn without anyone holding the full membership. HyParView was introduced by Leitão et al. (DSN 2007 — see references).
- Dissemination — eager-push gossip. Each paint operation is forwarded to a random fanout of active-view neighbours; receivers re-broadcast operations they haven't seen, de-duplicating by identifier, until the whole overlay has them. An optional bloom-filter anti-entropy layer recovers anything a gossip wave missed.
- Canvas application. Turns clicks into paint operations, broadcasts them, and applies every delivered operation to a last-writer-wins grid. The web UI is served by the JDK's built-in HTTP server — no extra dependencies.
- State sync — snapshot on join. Gossip only carries operations issued after a node joins, so a newcomer would otherwise start on a blank canvas and fill in only as fresh paints arrive. To catch up at once, a joining node asks one neighbour for a snapshot — the current winning operation for every painted cell — and merges it under the same last-writer-wins rule. These are three distinct jobs worth keeping straight: gossip spreads new changes, the snapshot hands over the accumulated state on join, and anti-entropy is the ongoing backstop that reconciles anything either path missed. The snapshot is an instant-catch-up convenience; durable agreement under loss or churn is guaranteed by anti-entropy.
The layers never call each other directly — they cooperate through the reusable babel-protocols-common abstractions (broadcast request/delivery, neighbour up/down, the shared-channel announcement), the very same building blocks our production protocols use.
Run it
You need Java 17 and Maven. Build the runnable JAR once:
mvn package
Then start a node. It serves a small web UI and opens your browser at it automatically
(it also prints the address — by default http://localhost:8000/; pass
canvas.ui.open=false to suppress the auto-open):
java -jar target/babel-canvas.jar
That's the whole demo on one node — paint a cell and you're drawing on the shared canvas. Start more nodes to watch them sync; how they find each other is just below.
Where this technology fits
A collaborative canvas is a friendly stand-in for a broad class of systems that need many parties to share state without a server in the middle. The same partial-view membership and gossip dissemination turn up in, for example:
- Edge and IoT fleets. Spreading configuration, feature flags, or device state across thousands of gateways and sensors with no central broker to provision or overload — the kind of decentralized, self-managing edge ParadigmShift's platform targets.
- Cluster membership and failure detection. Large-scale services gossip to track which nodes are alive and propagate that view quickly and resiliently — a backbone of distributed databases, caches, and orchestration layers.
- Real-time collaboration. Shared whiteboards, multiplayer editors, and live dashboards, where every participant both produces and consumes updates and they must converge to one state.
- Telemetry and event dissemination. Fanning metrics, logs, or alerts out to many collectors, or invalidating caches across a fleet, where a single broker is a bottleneck and a single point of failure.
- Decentralized networks. Block and transaction propagation in blockchains, and content distribution in peer-to-peer networks, lean on gossip overlays to reach every participant robustly as nodes come and go.
- Resilient field communications. Mesh deployments — disaster response, defence, remote sites — where infrastructure is intermittent and a server in the middle isn't an option.
What these share is the trade the demo makes visible: give up the central coordinator, and in return get a system that scales with its members, tolerates failure and churn, and offers no single point to attack or overload.
Running two (or more) nodes
A node joins by connecting to one node already in the overlay, and that first introduction happens one of two ways: automatically, by multicast — nodes on the same local network find each other with no addresses typed — or explicitly, by handing a node the address of an existing peer, which works anywhere two nodes can open a connection. Once a node is in, HyParView's gossip takes over and it discovers the rest on its own. Pick the option below that fits your setup.
How it works. Each node joins a well-known IP multicast group and periodically announces itself and listens on it; when one node hears another, the overlay introduces them — so nodes on the same network find each other with no addresses typed. Multicast isn't routed across the internet, so this works only within one local network, and a VPN, firewall, multi-NIC machine, or (recent macOS) the “Local Network” privacy permission can block it. It's opt-in: name the discovery protocol on the command line.
One node per machine on the same LAN — run this on each:
java -jar target/babel-canvas.jar \
babel.discovery=pt.unl.fct.di.novasys.babel.core.protocols.discovery.MulticastDiscoveryProtocol
To put two multicast nodes on one machine, also give each a distinct port and discovery socket:
DISC=babel.discovery=pt.unl.fct.di.novasys.babel.core.protocols.discovery.MulticastDiscoveryProtocol
java -jar target/babel-canvas.jar $DISC
java -jar target/babel-canvas.jar $DISC babel.port=6010 babel.discovery.unicast.port=1027
How it works. You tell a joining node where an existing one is with
HyParView.contact=<host>:<port>; it dials that peer to get into the
overlay, and HyParView's gossip does the rest — the contact is just the door in, not a coordinator or
relay. The first node (with nobody to contact) is marked HyParView.contact=none. This uses
no multicast at all — nothing extra to configure — so it works on one machine, across
networks, anywhere two nodes can open a TCP connection.
Two nodes on one machine, pinned to loopback:
# first node — the one others contact
java -jar target/babel-canvas.jar babel.address=127.0.0.1 babel.port=6000 HyParView.contact=none
# second node — dials the first to join
java -jar target/babel-canvas.jar babel.address=127.0.0.1 babel.port=6010 HyParView.contact=127.0.0.1:6000
Across machines, give the second node the first node's reachable address instead of 127.0.0.1.
Either way, to run several nodes on one machine give each a distinct babel.port
spaced by at least 10 (the gossip channel binds babel.port+1); the web-UI port
follows automatically. If a node auto-selects the wrong network interface, set
babel.interface=<nic> (e.g. en0, eth0) or
babel.address=<ip> explicitly — that always wins.
Source & credits
- Source code: github.com/ParadigmShift-PT/babel-canvas (downloadable release coming soon)
- This demo's API docs: paradigmshift-pt.github.io/babel-canvas (published from the repo on GitHub Pages; live once the first build runs)
- The framework libraries: Open Source · javadoc.paradigmshift.pt
babel-canvas is a ParadigmShift tech demo, built on ParadigmShift's own implementations of the Babel framework and of the two protocols beneath the canvas — HyParView membership and eager-push gossip broadcast. These protocols are established distributed-systems research: eager-push gossip is a foundational dissemination technique, dating to the early work on keeping replicated databases in sync by epidemic spread (Demers et al., 1987), and HyParView was introduced by Leitão et al. at DSN 2007 — both cited below. Our implementations, evolved, maintained, and distributed by ParadigmShift, descend from the original Babel, HyParView, and eager-push implementations developed at NOVA FCT by the Computer Systems Group of NOVA LINCS, in the context of the TaRDIS European project.
The protocols underpinning this demo are described in:
- A. Demers et al., “Epidemic Algorithms for Replicated Database Maintenance,” in Proc. 6th Annual ACM Symp. on Principles of Distributed Computing (PODC'87), Vancouver, Canada, Aug. 1987, pp. 1–12, doi: 10.1145/41840.41841.
- J. Leitão, J. Pereira, and L. Rodrigues, “HyParView: A Membership Protocol for Reliable Gossip-Based Broadcast,” in Proc. 37th Annual IEEE/IFIP Int'l Conf. on Dependable Systems and Networks (DSN'07), Edinburgh, UK, Jun. 2007, pp. 419–429, doi: 10.1109/DSN.2007.56. [PDF]
- P. Fouto, P. Á. Costa, N. Preguiça, and J. Leitão, “Babel: A Framework for Developing Performant and Dependable Distributed Protocols,” in Proc. 41st Int'l Symp. on Reliable Distributed Systems (SRDS), Vienna, Austria, Sep. 2022, pp. 146–155, doi: 10.1109/SRDS55811.2022.00022. [PDF]
Build with us
This demo is open source — read it, run it, fork it, and build your own application on top of Babel. We'd love to see what you make.