Skip to content

d-led/mermaidlive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mermaid Diagram Live Update Demo

Running

go run ./cmd/mermaidlive

http://localhost:8080/ui/

screencast

  • to change the default countdown delay, provide the option, e.g. -delay 150ms

Embedded Resources

to only generate UI resources from ui-src, run:

go run ./cmd/mermaidlive -transpile

to build a binary with embedded UI:

go build --tags=embed ./cmd/mermaidlive

Ideas Sketched in the Spike

  • developer experience of live reload back-endResourcesRefreshedfront-end
  • UI served from a binary-embedded filesystem
  • pub-sub long-polling connected clients and live viewers
  • asynchronously running state machine observable via published events
  • live re-rendering of a mermaid chart via events
  • initial rendering of a chart via the LastSeenState event published upon connecting to the stream
  • deployment on fly.io
  • sharing Gherkin features between unit, API and Browser tests, and sharing step implementations between scenarios
  • asynchronously connected client tests: two API and Browser clients
  • long poll re-connects and showing the connection status to the user
  • a persistent distributed G-Counter (grow-only counter) CRDT for started connections that is eventually-consistent, once service replicas see each other

Architecture

flowchart LR
    Server --serves---> UI
    StateMachine --runs on --> Server
    UI --posts commands to --> Server
    Server --forwards commands to -->StateMachine
    Server --publishes events to -->PubSub
    StateMachine --publishes events to -->PubSub
    Server --subscribes each connected client to -->PubSub
    Server --streams events to --> UI
Loading

Testing

  • the specification contains shared steps
  • state machine-level "unit" test steps
    • exececise the async state machine
  • API-level test steps
    • start the server at port 8081
    • exercise the specification, including scenarios tagged with @api
  • Browser-level: test steps

Unit

go test -v ./...

API-based

  • the test starts a temporary server instance and runs the tests against it
./scripts/test-api.sh

Browser-based

  • the test uses Playwright via the cucumber-playwright template
  • prerequisites:
    • install dependencies: npm i
    • initialize Playwright: npx playwright install
  • start the server first, e.g.:
./scripts/run-dev.sh -delay 150ms
  • run the tests:
./scripts/test-ui.sh

Approach

Deployment

Experiments

Observing Replication in Docker

to start 3 initial replicas:

docker compose up -d

→ visit and reload the UI: http://localhost:8080/

stop 2 replicas:

docker stop mermaidlive-mermaidlive-2 mermaidlive-mermaidlive-3

log:

mermaidlive-1 | Peers changed [172.19.0.4 172.19.0.5] -> []

reload the UI a couple of times and re-start the replicas:

docker start mermaidlive-mermaidlive-2 mermaidlive-mermaidlive-3

log:

mermaidlive-1 | Peers changed [] -> [172.19.0.4 172.19.0.5]
mermaidlive-1 | Connecting to tcp://[172.19.0.4]:5000
mermaidlive-1 | Connecting to tcp://[172.19.0.5]:5000
mermaidlive-2 | New visitor count: 25
mermaidlive-3 | New visitor count: 25
mermaidlive-2 | Peers changed [172.19.0.2] -> [172.19.0.2 172.19.0.5]
mermaidlive-2 | Connecting to tcp://[172.19.0.5]:5000
mermaidlive-3 | Peers changed [172.19.0.2] -> [172.19.0.2 172.19.0.4]
mermaidlive-3 | Connecting to tcp://[172.19.0.4]:5000

observe, how the replicated visitor count is propagated to the replicas.

Scale replicas for further experiments, e.g.:

docker compose scale mermaidlive=5

copying the replica file to the local filesystem reveals the structure of the G-Counter:

docker compose cp mermaidlive:/appdata/my.gcounter .

{
  "peers": {
    "3d226c43af66": 7,
    "c2206af9aba2": 9
  }
}

which results in the observable counter value of 16.