Skip to content
GitHubRSS

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.

ServiceModeResponsibility
SeederOne-shotLoad relay URLs from seed files and known relay lists
FinderContinuousDiscover new relay URLs from NIP-65 events and public APIs
ValidatorContinuousTest WebSocket connectivity and promote candidates to relay table
MonitorContinuousNIP-11 + NIP-66 health checks, optionally publish monitoring events
RefresherScheduledOrchestrate materialized view refresh cycles
SynchronizerContinuousCursor-based event collection from validated relays

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 writer database user.

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 calls run() 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 Logger class 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
...

Services that perform network I/O (Finder, Validator, Monitor, Synchronizer) support four network types through per-network configuration:

NetworkURL PatternProxy
Clearnetwss://relay.example.comDirect
Torws://abc.onionSOCKS5
I2Pws://abc.b32.i2pSOCKS5
Lokinetws://abc.lokiSOCKS5

Each network type has its own ClearnetConfig, TorConfig, I2pConfig, or LokiConfig with independent timeout, proxy_url, and max_tasks settings.

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.pyChunkProgress for cycle tracking, NetworkSemaphoresMixin for per-network concurrency control, GeoReaders for GeoIP database lifecycle.