id: local-dev
title: The whole stack runs on one machine, with traffic that looks real
status: continuous
crates: [didbot-swarm, didbot-serve]
dependsOn: []
exitCriterion: >
None. A development workflow is never finished; it is worked whenever
something adjacent to it is open. #
A terminal per script, each finding the others by default, and a swarm that
drives the stack with simulated agents. This is what makes every other epic
workable without a deployment.
A one-crate incremental rebuild of the development server is about two
seconds. A full dev-pds.sh cycle after a change to didbot-pds is
about fourteen, of which four is running that half's tests and the rest is
compiling and linking.
So the compile is not where the time goes. What the build costs is disk, and
that is what fills a machine: see the dev profile under Done.
Per user rather than per checkout. The agents on a machine address one
server on one port, and a second checkout on that port is refused by
`pds.lock` before it can write.
`DIDBOT_PDS_DATA=` is how a run asks for a clean slate, which is why
`scripts/dev-profile.sh` spells that one default `${NAME-value}` rather
than `${NAME:-value}`: the second treats an emptied variable as an
unset one and hands the default straight back.
One clone is shared by every checkout, so a plain run that fast-forwarded
it would move the corpus under whatever else is reading it. A corpus
already there is left alone and reported, and `--update` is what changes
it.
The personal data server watches too. It refuses under `DIDBOT_PDS_DATA=`: the others hold nothing and
a restart costs the build, while a server in memory rebuilds every
account, record and name hold on every save, so a watch there factory
resets the deployment and the first symptom is sessions whose accounts
have silently stopped existing. It says so and names the two ways to
mean it.
Polling rather than `inotifywait`, which is not on every machine this
runs on, and a second of latency against a rebuild that takes fourteen is
not worth a dependency that has to be installed first.
The stop tolerates its own signal: these scripts run under `set -e`, and
a `wait` on a process the loop just killed reports the signal. A stale
pidfile is harmless, because `exec` replaces the shell and takes any
cleanup trap with it.
The stamp is only worth something if somebody bumps it, so the durability
suite pins the on-disk shape against the number — the variants read out
of the source, and the fields read off a log the test writes and decodes
by hand rather than with the crate's own reader. A field rename fails it
with the instruction to bump.
The saving arrives on the next `cargo clean`. Cargo keeps artefacts it
has superseded, so a directory that has been built in for a while holds
both shapes and briefly grows.