Skip to content

service

service

Seeder service for BigBrotr.

Seeds initial relay URLs into the database as candidates for validation. This is a one-shot service intended to run once at startup to bootstrap relay discovery.

Relay URLs are read from a text file (one URL per line) and can be inserted either as validation candidates (picked up by Validator) or directly into the relays table.

Note

The seeder is the only one-shot service. Call run() once at startup; do not use run_forever(). In the default configuration (to_validate=True), seed URLs are inserted as candidates in service_state so that the Validator verifies them before promoting to the relay table.

See Also

SeederConfig: Configuration model for seed file path and insertion mode. BaseService: Abstract base class providing run() and from_yaml() lifecycle. Brotr: Database facade used for relay insertion. insert_candidates: Query used to insert seed URLs as validation candidates.

Examples:

from bigbrotr.core import Brotr
from bigbrotr.services import Seeder

brotr = Brotr.from_yaml("config/brotr.yaml")
seeder = Seeder.from_yaml("config/services/seeder.yaml", brotr=brotr)

async with brotr:
    await seeder.run()

Classes

Seeder

Seeder(brotr: Brotr, config: ConfigT | None = None)

Bases: BaseService[SeederConfig]

Database seeding service.

Reads relay URLs from a seed file and inserts them into the database. URLs can be added as validation candidates (for Validator to process) or inserted directly into the relays table.

This is a one-shot service; call run() once at startup.

See Also

SeederConfig: Configuration model for this service. Finder: Discovers additional relay URLs continuously.

Source code in src/bigbrotr/core/base_service.py
def __init__(self, brotr: Brotr, config: ConfigT | None = None) -> None:
    self._brotr = brotr
    self._config: ConfigT = (
        config if config is not None else cast("ConfigT", self.CONFIG_CLASS())
    )
    self._logger = Logger(self.SERVICE_NAME)
    self._shutdown_event = asyncio.Event()
Functions
run async
run() -> None

Execute the full seeding sequence: parse file and insert relays.

Source code in src/bigbrotr/services/seeder/service.py
async def run(self) -> None:
    """Execute the full seeding sequence: parse file and insert relays."""
    self._logger.info(
        "cycle_started",
        file=self._config.seed.file_path,
        to_validate=self._config.seed.to_validate,
    )
    inserted = await self.seed()
    self._logger.info("cycle_completed", inserted=inserted)
seed async
seed() -> int

Parse the seed file and insert relays.

Reads relay URLs from the configured seed file, validates them, then inserts them as validation candidates or directly into the relays table based on the to_validate configuration flag.

Returns:

  • int

    Number of relays inserted.

Source code in src/bigbrotr/services/seeder/service.py
async def seed(self) -> int:
    """Parse the seed file and insert relays.

    Reads relay URLs from the configured seed file, validates them,
    then inserts them as validation candidates or directly into the
    relays table based on the ``to_validate`` configuration flag.

    Returns:
        Number of relays inserted.
    """
    path = Path(self._config.seed.file_path)
    relays = await asyncio.to_thread(parse_seed_file, path)
    self._logger.debug("file_parsed", path=str(path), count=len(relays))

    if not relays:
        self._logger.info("no_valid_relays")
        return 0

    if self._config.seed.to_validate:
        return await self._seed_as_candidates(relays)
    return await self._seed_as_relays(relays)

Functions