billdogeng (Rust)
Official BilldogEng server SDK for Rust — the engagement suite for server-side use: Analytics, Feature Flags (remote + local evaluation), Surveys (data API), Messaging dispatch, and LLM observability.
This crate mirrors the canonical Node reference implementation
(billdogeng-node) idiomatically in Rust: a synchronous, thread-safe API with a
background flush thread for analytics batching.
Install
[]
= "1"
Quickstart
use HashMap;
use ;
use json;
let bd = new;
// ─ Analytics ─ (batched + flushed automatically)
bd.capture;
bd.identify;
bd.group_identify;
bd.alias;
// ─ Feature flags ─
let on = bd.is_feature_enabled?;
let variant = bd.get_feature_flag?; // Bool | Variant | None
let payload = bd.get_feature_flag_payload?;
let all = bd.get_all_flags?;
// ─ Surveys (data API) ─
let surveys = bd.surveys.list?;
let config = bd.surveys.fetch?;
// ─ Messaging dispatch ─ (Bearer JWT auth, not the API key)
bd.messaging.dispatch?;
// ─ LLM observability ─
bd.capture_trace?;
// Flush remaining events + stop the background thread before exit.
bd.shutdown?;
# Ok::
Configuration
| Option | Default | Description |
|---|---|---|
host |
https://api.billdog.io/v1 |
API base URL |
flush_at |
20 |
Batch size that triggers a flush |
flush_interval_ms |
10000 |
Background flush cadence (ms) |
max_queue_size |
1000 |
Drop oldest events past this many queued |
gzip |
true |
Gzip large request bodies |
local_evaluation |
false |
Evaluate feature flags locally (server-only) |
request_timeout_ms |
10000 |
Per-request timeout (ms) |
max_retries |
3 |
Retry attempts for 5xx / 429 / network errors |
group_type_index |
— | Stable group-type → $group_0..4 index map |
enable_logging |
false |
Verbose diagnostics to stderr |
Authentication uses the x-api-key: <apiKey> header (bd_test_* sandbox /
bd_live_* live) on every request, except messaging dispatch, which
authenticates with a Supabase session Bearer JWT + project membership.
Analytics batching & delivery
- Events accumulate in an in-memory queue and ship as a single batched POST
to
/ingest-events. - A flush happens on
flush_at, everyflush_interval_ms, or onflush()/shutdown(). - Failed flushes re-queue their batch (never lose events on a transient failure); the transport also retries with exponential backoff (1s, 2s, 4s).
- Bodies are gzip-compressed when large enough to benefit.
Feature flags — local evaluation
With local_evaluation: true, the SDK fetches flag definitions once
(POST /feature-flag-definitions), caches them for 5 minutes, and evaluates
deterministically on-process:
- missing/inactive →
false - ALL
targeting_rulesmust matchperson_properties, elsefalse bucket = murmurhash3("{key}.{distinctId}") % 100; ON iffbucket < rollout_percentage- multivariate: walk
variantsby cumulative rollout within the ON bucket → variant key
The murmurhash3 (32-bit, seed 0) implementation is byte-identical across web / iOS / Android / all server SDKs, so a user buckets the same everywhere.
Build & test
License
MIT