Packages

Population Protocol federation layer for EmergenceSystem

Current section

Files

Jump to
em_pop README.md
Raw

README.md

# em_pop
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE.md)
**Population Protocol federation layer for [Emergence](https://github.com/EmergenceSystem).**
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
```erlang
%% rebar.config
{deps, [{em_pop, "0.2.0"}]}.
```
## Usage
```erlang
%% 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/3`
ranks them by cosine similarity (via [kvex](https://hex.pm/packages/kvex)), so a
query goes to the peers most likely to answer it.
- **Stale eviction.** Peers not heard from within `stale_timeout` are dropped.
The gen_server never blocks on HTTP: gossip is asynchronous.
## Requirements
- Erlang/OTP 27+, [rebar3](https://rebar3.org).
## Build & test
```bash
rebar3 compile
rebar3 ct
```
## License
Apache License 2.0 — see [LICENSE](LICENSE.md).