em_pop
Population Protocol federation layer for Emergence. em_pop is the gossip substrate every Emergence agent runs: a node holds a peer table, advertises a semantic capability vector, and continuously exchanges state with its peers over HTTP. Any node can then ask "which peers best match this query vector?" and route work to them — the mesh self-assembles, with no central registry.
Install
%% rebar.config
{deps, [{em_pop, "0.2.0"}]}.
Usage
%% start a node: it listens for gossip and advertises MyCapabilityVector
{ok, Node} = em_pop:start_link(#{
port => 9100,
vector => MyCapabilityVector, %% f32 flat binary
stale_timeout => 30000, %% optional, default 30s
gossip_interval => 5000 %% optional, default 5s (0 = manual)
}),
%% seed from a known peer; from then on gossip discovers the rest
ok = em_pop:add_peer(Node, "other-host", 9101),
%% (a background loop gossips every gossip_interval; or drive it yourself)
ok = em_pop:gossip_tick(Node),
%% route: the top-3 peers whose capability vector is closest to QueryVec
[{PeerMap, Score} | _] = em_pop:peers_for(Node, QueryVec, 3).
API
| Function | Purpose |
|---|---|
start_link/1 | Start a node (#{port, vector, stale_timeout, gossip_interval}) |
stop/1 | Stop a node and free its port |
id/1 | This node's unique binary id |
vector/1 | The capability vector the node advertises |
add_peer/3 | Seed a peer by Host, Port |
peers/1 | All currently known peers |
peers_for/3 | Top-K peers by cosine similarity to a query vector |
trust/2 | Trust score for a given peer |
gossip_tick/1 | Run one gossip round synchronously |
How it works
- Gossip. Each node periodically POSTs its peer table to a known peer
(
POST /pop/gossip, bidirectional state exchange). New peers propagate transitively, so seeding from one well-connected node joins the whole network. - Semantic routing. Peers advertise an f32 capability vector;
peers_for/3ranks them by cosine similarity (via kvex), so a query goes to the peers most likely to answer it. - Stale eviction. Peers not heard from within
stale_timeoutare dropped.
The gen_server never blocks on HTTP: gossip is asynchronous.
Requirements
- Erlang/OTP 27+, rebar3.
Build & test
rebar3 compile
rebar3 ct
License
Apache License 2.0 — see LICENSE.