Services Overview
BigBrotr runs six independent services. Each service is a separate process with a single responsibility. Services communicate exclusively through the shared PostgreSQL database — there are no message queues, no inter-service APIs, and no orchestration layers.
Service Summary
Section titled “Service Summary”| Service | Mode | Responsibility |
|---|---|---|
| Seeder | One-shot | Load relay URLs from seed files and known relay lists |
| Finder | Continuous | Discover new relay URLs from NIP-65 events and public APIs |
| Validator | Continuous | Test WebSocket connectivity and promote candidates to relay table |
| Monitor | Continuous | NIP-11 + NIP-66 health checks, optionally publish monitoring events |
| Refresher | Scheduled | Orchestrate materialized view refresh cycles |
| Synchronizer | Continuous | Cursor-based event collection from validated relays |
Independence
Section titled “Independence”Each service:
- Runs as its own process with its own configuration file.
- Has its own run cycle — continuous services loop indefinitely with configurable sleep intervals; one-shot services (Seeder) exit after a single cycle.
- Scales independently — you can run multiple Finder instances or skip the Synchronizer entirely.
- Fails independently — if the Monitor crashes, the Validator keeps running.
- Connects to the database through PgBouncer using the
writerdatabase user.
BaseService
Section titled “BaseService”All six services inherit from BaseService[ConfigT], a generic abstract base class that provides:
run()— abstract method implementing one work cycle.run_forever()— loop that callsrun()repeatedly with sleep intervals and graceful shutdown.from_yaml()/from_dict()— factory methods that construct the service from YAML configuration.- Prometheus metrics — automatic cycle duration, service info, and custom counters.
- Structured logging — via the
Loggerclass with key=value format. - Graceful shutdown — handles SIGINT/SIGTERM for clean process termination.
class Finder(BaseService[FinderConfig]): """Discovers relay URLs from events and APIs."""
async def run(self) -> None: # One work cycle: scan events, query APIs, insert candidates ...Network Support
Section titled “Network Support”Services that perform network I/O (Finder, Validator, Monitor, Synchronizer) support four network types through per-network configuration:
| Network | URL Pattern | Proxy |
|---|---|---|
| Clearnet | wss://relay.example.com | Direct |
| Tor | ws://abc.onion | SOCKS5 |
| I2P | ws://abc.b32.i2p | SOCKS5 |
| Lokinet | ws://abc.loki | SOCKS5 |
Each network type has its own ClearnetConfig, TorConfig, I2pConfig, or LokiConfig with independent timeout, proxy_url, and max_tasks settings.
Shared Infrastructure
Section titled “Shared Infrastructure”The services/common/ package provides building blocks used across all services:
configs.py— per-network Pydantic configuration models with sensible defaults.queries.py— 15 domain-specific SQL query functions, centralized to avoid scattering inline SQL.mixins.py—ChunkProgressfor cycle tracking,NetworkSemaphoresMixinfor per-network concurrency control,GeoReadersfor GeoIP database lifecycle.