···11#### table-of-contents
2233-> [hydrant](#hydrant)</br>
44--> [vs tap](#vs-tap)</br>
44+-> [vs tap](#vs-tap) | [stream](#stream-behavior) | [multi-relay](#multiple-relay-support) | [crawler sources](#crawler-sources)</br>
55-> [configuration](#configuration)</br>
66-> [rest api](#rest-api) | [filter](#filter-management) | [ingestion](#ingestion-control) | [crawler](#crawler-management) | [firehose](#firehose-management) | [repos](#repository-management)</br>
77-> [xrpc api](#data-access-xrpc) | [backlinks](#bluemicrocosmlinks) | [atproto](#comatproto) | [custom](#systemsgazehydrant)
···40404141### stream behavior
42424343+<small>[<- back to toc](#table-of-contents)</small>
4444+4345the `WS /stream` (hydrant) and `WS /channel` (tap) endpoints have different designs:
44464547| aspect | `tap` (`/channel`) | `hydrant` (`/stream`) |
···52545355### multiple relay support
54565757+<small>[<- back to toc](#table-of-contents)</small>
5858+5559`hydrant` supports connecting to multiple relays simultaneously for firehose
5660ingestion. when `RELAY_HOSTS` is configured with multiple URLs:
5761···6468relay-side account takedowns or if relays set the `time` field.
65696670### crawler sources
7171+7272+<small>[<- back to toc](#table-of-contents)</small>
67736874the crawler is configured separately from the firehose via `CRAWLER_URLS`. each
6975source is a `[mode::]url` entry where the mode prefix is optional and defaults
+7-7
src/control/mod.rs
···557557 ///
558558 /// - if `cursor` is `None`, streaming starts from the current head (live tail only).
559559 /// - if `cursor` is `Some(id)`, all persisted `record` events from that ID onward are
560560- /// replayed first, then live events follow seamlessly.
560560+ /// replayed first, then the stream will switch to live tailing.
561561 ///
562562- /// `identity` and `account` events are ephemeral and are never replayed from a cursor -
563563- /// only live occurrences are delivered. use [`ReposControl::get`] to fetch current
564564- /// identity/account state for a specific DID.
562562+ /// `identity` and `account` events are ephemeral and are never replayed from a cursor,
563563+ /// only live ones are delivered. use [`ReposControl::info`] to fetch current state for
564564+ /// a specific repository.
565565 ///
566566 /// multiple concurrent subscribers each receive a full independent copy of the stream.
567567 /// the stream ends when the `EventStream` is dropped.
···651651652652 /// returns a future that runs the debug HTTP API server on `127.0.0.1:{port}`.
653653 ///
654654- /// exposes internal inspection endpoints (`/debug/get`, `/debug/iter`, etc.)
655655- /// that are not safe to expose publicly. binds only to loopback.
654654+ /// exposes internal inspection endpoints (`/debug/get`, `/debug/iter`, etc.).
655655+ /// binds only to loopback.
656656 pub fn serve_debug(&self, port: u16) -> impl Future<Output = Result<()>> {
657657 let state = self.state.clone();
658658 async move { crate::api::serve_debug(state, port).await }
···734734735735 /// train zstd compression dictionaries for the `repos`, `blocks`, and `events` keyspaces.
736736 ///
737737- /// dictionaries are written to `dict_{name}.bin` files next to the database.
737737+ /// dictionaries are written to `dict_{name}.bin` files inside the database folder.
738738 /// a restart is required to apply them. training samples data blocks from the
739739 /// existing database, so the database must have a reasonable amount of data first.
740740 pub async fn train_dicts(&self) -> Result<()> {
+3
src/control/repos.rs
···130130 /// note that they may not immediately start backfilling if:
131131 /// - other repos already filled the backfill concurrency limit,
132132 /// - or there are many repos pending already.
133133+ ///
134134+ /// this will also clear any error state the repo may have been in,
135135+ /// allowing it to resync again.
133136 pub async fn resync(
134137 &self,
135138 dids: impl IntoIterator<Item = Did<'_>>,