Ecosystem Spotlight: swap – evergreen one-shot atomic exchange CLI

Ship a command as a standalone binary that updates itself peer-to-peer. swap is an applied demonstration of a peer-to-peer installable self-updating single-operation program. This is the first in our Ecosystem Spotlight series, looking at the libraries, tools and applications growing out of the Ecosystem of Pears.

swap atomically exchanges two filesystem paths and keeps itself current with peer-to-peer over-the-air updates.

Atomic Exchange

There’s no standard command to atomically exchange two filesystem paths. 

On Linux & macOS the kernels have had the primitive for years: renameat(2) with RENAME_EXCHANGE on Linux, renamex_np with RENAME_SWAP on macOS. Windows lacks the atomic exchange primitive, so swap falls back to a temporary path to keep the behaviour consistent.

The swap program takes source and target paths and atomically switches the pointers of each path to point at the other path.

swap <source> <target>

Without swap it takes three renames:  target to tmp, source to target, then tmp to source. This creates a window of time where neither path is where it should be. The solution to this situation is atomic exchange.

Simple example, updating builds folder containing downloadable releases with mv:

mv ./builds ./tmp # builds is now unavailable
mv ./next-builds ./builds # builds is now available again
mv ./tmp ./prior-builds

If there’s any requests between those operations, the builds folder is unavailable to users. If there’s a power-cut in between those operations it can lead to a missing builds folder.

With swap there is no opportunity for a missing file/directory:

swap ./next-builds ./builds # builds is never unavailable
mv ./next-builds ./prior-builds

Evergreen

swap is built on the hello-pear-bare boilerplate: the application and the Bare runtime compile into one standalone executable per OS and architecture..

Updates flow peer-to-peer — new builds are published with the Pear CLI and applied in place by pear-runtime, which tracks the upgrade link in package.json.

Once installed the binary keeps itself current per any deployments via Pear CLI.. It’s unlikely that swap will need to be updated much beyond security-mandated dependency-bumps, support for new hardware architectures in future and changes in multisig signing keys. An evergreen contract with very low update frequency is ideal.

Daemon boilerplate

In the Hello Pear Boilerplates article we introduced hello-pear-bare boilerplate for building Bare terminal programs and deploying them peer-to-peer with pear. On the  main branch of hello-pear-bare updates occur in a worker using hello-pear-worker boilerplate as a local backend. The idea is that terminal, desktop and mobile all use the same local backend worker for updates and application peer-to-peer logic. For terminal programs this architecture is compatible with a long-lived processes such as a Read-Eval-Print-Loop (REP),  a Terminal User Interface (TUI) or a background service. 

swap is based on the variant/daemon branch of hello-pear-bare, a daemon updater makes most sense for a command that performs one operation and then exits.

An update check has to reach the peer-to-peer network and wait for peers, which takes seconds — too long to block before the operation with no reason to keep the process alive after the operation.

So swap spawns a detached updater daemon via bare-daemon that outlives the parent, checks the network, applies any update, and exits.

The daemon is polite and safe with the following characteristics

  • Single updater. A file lock means only one daemon runs; a second exits immediately.
  • Cooldown. The daemon stamps the lock file’s mtime each check; if one ran within the cooldown (20 minutes by default), the spawn is skipped. Can be set with –update-cooldown flag.
  • Bounded window. waits up to –update-window (30s default) to discover an update
  • Logging. With no terminal I/O output goes to <storage>/updates.log which rotates per max cap (1MB).

Install swap peer-to-peer

If pear is installed on the machine swap can also be installed peer-to-peer using the pear install command.

pear install pear://swapb14acos6iasoz5jg8bj46zt8emdk9rmm4n9j18mtjmwbqmwo

To build from source, clone the repo, npm install, and npm run make for your host, or target any of darwin-arm64, darwin-x64, linux-arm64, linux-x64, win32-arm64, win32-x64. To make your own peer-to-peer installable & updatable  binaries, start from the hello-pear-bare boilerplate.

Ecosystem growth

The swap program is a demonstrative drop in the ocean of the possibilities of Pear and peer-to-peer programming. Watch out for future articles in the Ecosystem Spotlight series where we’ll be highlighting use cases, implementations, modules, tools, practices and happenings in the Ecosystem of Pears.

Join the Pear Development group on Keet to share what you’re building and follow the ecosystem as it grows.