Expand description
The archiver binary: writes LabJack scans from NATS JetStream to Parquet files.
For every LabJack read, the streamer publishes one FlatBuffer Scan per channel to
the local NATS JetStream. The archiver reads the same dashboard configuration as the
streamer (from KV bucket avenabox by default), attaches one durable pull consumer
per enabled channel, rebuilds each sample’s timestamp from the scan header, and writes the
samples to Parquet files under
<PARQUET_DIR>/asset<NNN>/<YYYY-MM-DD>/ch<NN>/part-<NNNN>.parquet. Each file carries
the channel’s calibration as key-value metadata. The exporter later serves these files
as CSV over NATS.
At startup the archiver can mirror the configuration entry from a central NATS server into local KV, and it keeps mirroring updates in a background task. It then watches the local KV key and starts, stops or restarts channel writers as the configuration changes. Ctrl-C closes every open file and acks its messages before the process exits.
§Configuration
NATS_SERVERS- Comma-separated local NATS server URLs. Default:nats://127.0.0.1:4222.NATS_CREDS_FILE- Credentials file for the local NATS connection. Default:apt.creds.JS_DOMAIN- Optional JetStream domain for the local connection.PARQUET_DIR- Root directory for Parquet output. Default:parquet.CFG_BUCKET- Local KV bucket holding the dashboard configuration. Default:avenabox. Also the fallback forCENTRAL_CFG_BUCKET.CFG_KEY- Local KV key holding the dashboard configuration. Default:labjackd.config.macbook. Also the fallback forCENTRAL_CFG_KEY.CENTRAL_NATS_SERVERS- Central NATS server URLs to mirror configuration from. Central mirroring is off when neither this norCFG_NATS_SERVERSis set.CFG_NATS_SERVERS- Fallback forCENTRAL_NATS_SERVERS.CENTRAL_CFG_BUCKET- Central KV bucket to mirror from. Default:CFG_BUCKET, thenavenabox.CENTRAL_CFG_KEY- Central KV key to mirror from. Default:CFG_KEY, thenunknown-site.macbook.unknown-source.config.CENTRAL_JS_DOMAIN- Optional JetStream domain on the central server. Falls back toCFG_JS_DOMAIN.CENTRAL_NATS_CREDS_FILE- Credentials file for the central server. Default: the value used forNATS_CREDS_FILE.ARCHIVER_STATE_DIR- Directory for the replay-guard checkpoints. Default:<PARQUET_DIR>/.archiver-state.ARCHIVER_REPLAY_GUARD-off(or0,false,no) turns the replay guard off.
§Design
- Aligned source-time rotation. A file covers one window of
rotate_secsthat starts at a multiple ofrotate_secssince the Unix epoch (seerotation_window), measured in sample time rather than wall-clock time. Files line up across channels, and replaying a backlog of several hours still produces one file per window. A new file also starts at a UTC date change or when sample time goes backwards. - One row group per file. A row group holds up to
ROWS_PER_ROW_GROUProws, which is more than a normal window, so a file is usually a single row group. Files are written with zstd compression and delta-encoded timestamps (seearchive_format::writer_properties). - Acks after close and fsync. A JetStream message is acked only after every sample
in it is inside a file that has been closed, fsynced and renamed from
.parquet.inprogressto.parquet(seeParquetLogger::close). If the process or machine dies first, the messages stay unacked and JetStream redelivers them once the consumer’sack_waitexpires, so they are written again into a new file. - Early close at the pending-ack cap. When a file holds
MAX_PENDING_ACKS_PER_FILEunacked messages it is closed early, which keeps the consumer below itsmax_ack_pendinglimit (CONSUMER_MAX_ACK_PENDING) so delivery never stalls. - Idle close. A file that has received no data for
IDLE_CLOSE_AFTERis closed, for example after the streamer stops, so its messages are acked promptly. - Quarantine of unfinished files. At startup every leftover
.parquet.inprogressfile (no footer, from a crash) is renamed aside and kept for diagnosis (seequarantine_incomplete_files). Its samples come back through redelivery. - Replay guard. JetStream can lose a durable consumer’s progress (its state file
is replaced without an fsync, so a power cut can leave it empty) and then deliver
the whole stream again under deliver policy
all. Each channel saves the consumer’s ack floor to its own fsynced checkpoint and acks messages at or below it without writing them (seeReplayStateandreplay_guard). - Filters are never edited in place. When a channel’s subject changes, an existing
consumer with the old filter is left alone and a consumer named after the new
subject is used (see
filtered_consumer_name).
Modules§
- archive_
format 🔒 - On-disk format shared by the archiver and the recompress tool.
- calibration 🔒
- Calibration formulas stored with archived channel data.
- nats_
config 🔒 - Shared NATS server-list and JetStream context helpers.
- replay_
guard 🔒 - Protection against JetStream replaying messages the archiver already wrote.
- sample_
data_ 🔒generated - subjects 🔒
- NATS subject builders for LabJack live data and archive exports.
Structs§
- Central
KvSync 🔒Config - Connection and key details for mirroring dashboard config from central NATS.
- Channel
Logger 🔒 - Runtime state for one active channel consumer and writer task.
- Close
Outcome 🔒 - Files closed while handling one payload.
- Nested
Config 🔒 - Raw top-level dashboard configuration loaded from NATS KV.
- Parquet
Logger 🔒 - Buffered writer for one channel’s Parquet file.
- Replay
State 🔒 - Replay protection for one channel writer.
- Sample
Config 🔒 - Normalized archiver configuration used to manage channel loggers.
- Sensor
Config 🔒 - Raw sensor settings section from the dashboard configuration.
Constants§
- CHECKPOINT_
INTERVAL 🔒 - How often each writer task saves its replay-guard checkpoint (60 s).
- CONSUMER_
MAX_ 🔒ACK_ PENDING max_ack_pendingset on each durable consumer, in messages.- IDLE_
CHECK_ 🔒INTERVAL - How often each writer task checks for an idle file (15 s).
- IDLE_
CLOSE_ 🔒AFTER - Time without new data after which the open file is closed (60 s).
- MAX_
PENDING_ 🔒ACKS_ PER_ FILE - Unacked messages that force the open file to close early.
- MAX_
ROW_ 🔒GROUPS_ PER_ FILE - Maximum row groups in one file before it is rotated.
- ROWS_
PER_ 🔒ROW_ GROUP - Rows buffered before they are written as one row group (1,048,576).
- SKIP_
LOG_ 🔒EVERY - Skipped messages between two progress lines while the replay guard is skipping.
Functions§
- ack_
messages 🔒 - Acks messages whose samples are all inside closed, synced Parquet files.
- archiver_
consumer_ 🔒config - Consumer settings that let acks wait until a file is closed.
- archiver_
consumer_ 🔒name - Builds the durable JetStream consumer name for one archived channel.
- central_
kv_ 🔒sync_ config_ from_ env - Builds optional central KV mirroring settings from environment variables.
- close_
and_ 🔒settle - Closes the open file (if any) and settles the messages it holds.
- connect_
nats_ 🔒with_ creds - Connects to NATS with a credentials file and explicit server list.
- ensure_
kv_ 🔒bucket - Opens or creates the KV bucket that contains dashboard configuration.
- env_
nonempty 🔒 - Returns a trimmed environment variable value when it is set and non-empty.
- filtered_
consumer_ 🔒name - Durable consumer name used when the base consumer filters on another subject.
- main 🔒
- Starts the archiver service and reacts to configuration updates.
- mirror_
central_ 🔒kv_ once - Copies the configured central KV entry into local KV during startup.
- next_
file_ 🔒index - Scans a channel/day directory to find the next available Parquet file index.
- parse_
calibrations 🔒 - Parses dashboard calibration map keys into numeric LabJack channels.
- process_
scan_ 🔒payload - Decodes one FlatBuffer scan payload and writes its samples to Parquet.
- quarantine_
incomplete_ 🔒files - Renames unfinished writer files under
rootso they are kept but never read. - replay_
state_ 🔒dir - Pure part of
replay_state_dir_from_env. - replay_
state_ 🔒dir_ from_ env - Reads the replay-guard settings.
- representable_
samples 🔒 - Counts the leading samples of a scan whose timestamps fit in an
i64. - rotation_
window 🔒 - Returns the index of the aligned rotation window holding a timestamp.
- run_
central_ 🔒kv_ sync - Continuously mirrors central KV updates into the local configuration bucket.
- sample_
config_ 🔒from_ nested - Converts the nested dashboard configuration into archiver runtime config.
- sample_
timestamp_ 🔒ns - Computes the Unix timestamp for a sample index within a FlatBuffer scan.
- sanitize_
consumer_ 🔒token - Converts source identity text into a durable consumer-name token.
- spawn_
channel_ 🔒logger - Starts the durable pull consumer and writer task for one channel.
- sync_
directory_ 🔒after_ publish - Fsyncs the directory of a file that has just been renamed into place.
- timestamp_
ns_ 🔒to_ utc_ date - Converts a Unix nanosecond timestamp to its UTC calendar date.
Type Aliases§
- DynError 🔒
- Error type used by the archiver for fallible async setup and IO paths.