mirror of
https://github.com/hanzoai/insights.git
synced 2026-10-30 16:15:31 +00:00
`insights-rs = { package = "posthog-rs" }` reads as ours everywhere in our
source and installs theirs on the machine. The upstream name is what lands in
the lockfile, in site-packages, and in the stack trace. `--check` was green over
that line for as long as it has existed, because it reads source and this is a
specifier.
Three of the six are settled here.
statshog is gone. It was a third-party fork of pystatsd whose only addition was
Telegraf tags, and this instance used three of its methods -- incr, gauge, and a
timer -- through a single import repeated in eleven files. insights/statsd.py
does that in 87 lines. It was checked rather than assumed: every call shape in
the tree driven through both clients, compared metric for metric, identical in
the configuration we deploy. It also does not carry upstream's negative-gauge
fault, where Pipeline never copies the separator and a gauge below zero raises
AttributeError into the caller as soon as STATSD_PREFIX is set -- a measurement
breaking the request that emitted it.
STATSD_CLIENT and STATSD_TELEGRAF go with it. Nothing read the first; the second
was pinned True, so the dialect is not a choice, it is what the client writes.
rust/Cargo.toml's posthog-rs entry is deleted rather than forked, because
nothing consumes it. It sits in [workspace.dependencies], which is inert until a
member opts in, and no member does: rust/Cargo.lock resolves zero posthog
packages while resolving every dependency that is really used. Forking it would
have been work for a line that could just go.
The rest is the guard, which is the part that lasts. check_upstream_deps parses
the manifests rather than grepping them, so it sees the alias target, the git
URL and the tag as distinct from a comment on the same line, and refuses any
specifier that resolves upstream and is not written down. The five still
outstanding are written down, each with the decision that retires it -- and the
ledger is checked in both directions, so an entry that outlives its dependency
fails too rather than quietly granting permission for a name nothing takes.
The lockfile edit is by hand and is eleven deleted lines: uv here is 0.5.7 and
pyproject requires >=0.10.2, so `uv lock` cannot run at all, and statshog was a
leaf with no dependents and no dependencies of its own.
Not fixed here, and worse than it looks: cli/build.rs pins a PostHog project
key for debug builds, and cli never calls .host() on the client, so the crate's
DEFAULT_HOST applies. Debug builds of insights-cli report telemetry and captured
panics to us.i.posthog.com.
250 lines
9.3 KiB
TOML
250 lines
9.3 KiB
TOML
[workspace]
|
||
resolver = "2"
|
||
|
||
members = [
|
||
"capture",
|
||
"capture-logs",
|
||
"common/alloc",
|
||
"common/compression",
|
||
"common/continuous_profiling",
|
||
"common/health",
|
||
"common/ingestion_warnings",
|
||
"common/kafka",
|
||
"common/lifecycle",
|
||
"common/limiters",
|
||
"common/liveness",
|
||
"common/metrics",
|
||
"common/redis",
|
||
"common/types",
|
||
"cyclotron-core",
|
||
"cyclotron-janitor",
|
||
"cyclotron-node",
|
||
"deltalite/core",
|
||
"deltalite/python",
|
||
"replay-anonymizer",
|
||
"replay-anonymizer-node",
|
||
]
|
||
|
||
# `insightsql/parser` declares its OWN `[workspace]` (see its Cargo.toml: it is
|
||
# built standalone, by a python stage that copies only that directory, so cargo
|
||
# must stop searching upward). A crate cannot be both a member here and a
|
||
# workspace root there — cargo refuses the whole tree with "multiple workspace
|
||
# roots found in the same workspace" and names the two paths, which stops every
|
||
# build in this workspace, cyclotron-node included, not just the parser's.
|
||
#
|
||
# Excluding it keeps both halves true. Nothing here depends on it: deltalite/
|
||
# python's only path dependency is `../core`, and its mentions of the parser are
|
||
# comments pinning the pyo3 major the two must share.
|
||
exclude = [
|
||
"insightsql/parser",
|
||
]
|
||
|
||
# NOTE: cargo allows only one crate with `links = "python"` (i.e. one pyo3 version) per
|
||
# dependency graph. `insightsql/parser` and `deltalite/python` must therefore agree on their
|
||
# pyo3 major (currently 0.28, dictated by arrow 58's `pyarrow` feature in deltalite) --
|
||
# bumping pyo3 in one means bumping it in the other, or the workspace stops resolving.
|
||
|
||
[workspace.lints.rust]
|
||
# See https://doc.rust-lang.org/stable/rustc/lints/listing/allowed-by-default.html
|
||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
|
||
unstable_features = "forbid"
|
||
macro_use_extern_crate = "forbid"
|
||
let_underscore_drop = "deny"
|
||
non_ascii_idents = "deny"
|
||
trivial_casts = "deny"
|
||
trivial_numeric_casts = "deny"
|
||
unit_bindings = "deny"
|
||
|
||
[workspace.lints.clippy]
|
||
# See https://rust-lang.github.io/rust-clippy/, we might want to add more
|
||
enum_glob_use = "deny"
|
||
# Inert for every crate that ships no `clippy.toml` `disallowed-methods` list (all of them but
|
||
# `cohort-stream-processor`, whose list confines async code to the `StoreHandle` facade).
|
||
disallowed_methods = "deny"
|
||
|
||
# this is needed until getsentry/symbolic update the js-source-scopes to >0.6.0
|
||
# I made a PR for the upstream fix here https://github.com/getsentry/symbolic/pull/945
|
||
[patch.crates-io]
|
||
js-source-scopes = { git = "https://github.com/getsentry/js-source-scopes", rev = "abea51a0e74840a8d1ec96a61ff36b488994f68c" }
|
||
|
||
# Emit DWARF line tables in release builds so backtrace-rs can resolve frame
|
||
# symbols for continuous profiling (pyroscope). Without this, release binaries
|
||
# on Linux expose raw _ZN…E names in the pyroscope UI because gimli-symbolize
|
||
# has no debug info to read from. line-tables-only is the cheapest level that
|
||
# still gives usable function names + file:line info at sample time; expect
|
||
# roughly 5–15% binary size increase on Linux. Debug info must stay embedded
|
||
# (no split-debuginfo) since backtrace-rs reads it at runtime.
|
||
[profile.release]
|
||
debug = "line-tables-only"
|
||
|
||
# The stateright model checker exhaustively explores millions of protocol
|
||
# states; its hot loop (state hashing, BTreeMap clones) is ~11x slower
|
||
# unoptimized, which would put the exhaustive tests at ~25 minutes in
|
||
# debug-profile CI runs instead of ~2. Compile the checker and the model
|
||
# crate with release-grade codegen even in dev builds — this changes
|
||
# nothing about behavior (debug assertions and overflow checks stay on),
|
||
# only how hard LLVM optimizes these two packages.
|
||
[profile.dev.package.personinsights-stateright]
|
||
opt-level = 3
|
||
|
||
[profile.dev.package.stateright]
|
||
opt-level = 3
|
||
|
||
# The model's rebalance action runs the production placement computation
|
||
# (plan_partial_rebalance, the sticky strategy, the handoff diff) in every
|
||
# explored state, so the crates that host it need the same treatment or
|
||
# the checker's hot loop drops back to opt-level 0.
|
||
[profile.dev.package.personinsights-coordination]
|
||
opt-level = 3
|
||
|
||
[profile.dev.package.assignment-coordination]
|
||
opt-level = 3
|
||
|
||
[workspace.dependencies]
|
||
aho-corasick = "1.1"
|
||
anyhow = "1.0"
|
||
arc-swap = "1.7"
|
||
assert-json-diff = "2.0.2"
|
||
async-compression = { version = "0.4", features = [
|
||
"tokio",
|
||
"gzip",
|
||
"deflate",
|
||
"zlib",
|
||
"brotli",
|
||
"zstd",
|
||
] }
|
||
async-stream = "0.3"
|
||
async-trait = "0.1.74"
|
||
axum = { version = "0.7.5", features = ["http2", "macros", "matched-path"] }
|
||
axum-client-ip = "0.6.0"
|
||
base64 = "0.22.0"
|
||
bytes = "1"
|
||
clap = { version = "4", features = ["derive"] }
|
||
chrono = { version = "0.4.44", features = ["default", "serde"] }
|
||
chrono-tz = "0.10.1"
|
||
dashmap = "6.1"
|
||
envconfig = "0.10.0"
|
||
eyre = "0.6.9"
|
||
flate2 = "1.0"
|
||
futures = { version = "0.3.29" }
|
||
futures-timer = "3.0"
|
||
futures-util = { version = "0.3.31" }
|
||
governor = { version = "0.5.1", features = ["dashmap"] }
|
||
hdrhistogram = "7.5"
|
||
http = { version = "1.1.0" }
|
||
humantime = "2.1"
|
||
http-body = "1.0"
|
||
http-body-util = "0.1"
|
||
httpmock = "0.7.0"
|
||
mockito = "1"
|
||
hyper = { version = "1.9.0", features = ["server", "http1", "http2"] }
|
||
# default-features off on purpose: the defaults drag in native-tokio (rustls-native-certs), and the
|
||
# `datastore` crate already pins this dependency with defaults off. Enabling them here would flip
|
||
# the feature set for every consumer of the shared dependency.
|
||
hyper-rustls = { version = "0.27.7", default-features = false, features = ["aws-lc-rs", "http1", "tls12"] }
|
||
hyper-util = { version = "0.1.20", features = ["server", "server-graceful", "tokio", "http1", "http2"] }
|
||
itoa = "1.0.15"
|
||
libdeflater = "1"
|
||
metrics = "0.22.0"
|
||
metrics-exporter-prometheus = "0.14.0"
|
||
metrics-util = "0.16.0"
|
||
once_cell = "1.21.4"
|
||
opentelemetry = { version = "0.22.0", features = ["trace"] }
|
||
opentelemetry-otlp = "0.15.0"
|
||
opentelemetry_sdk = { version = "0.22.1", features = ["trace", "rt-tokio"] }
|
||
public-suffix = "0.1.2"
|
||
prost = "0.13"
|
||
rand = "0.8.5"
|
||
rdkafka = { version = "0.37.0", features = ["tracing", "ssl-vendored"] }
|
||
reqwest = { version = "0.12.3", features = ["json", "stream"] }
|
||
# Matches the provider `datastore`'s `rustls-tls` feature selects, so a direct `rustls::ClientConfig`
|
||
# is built against the same crypto backend the crate would have used itself.
|
||
rustls = { version = "0.23", default-features = false, features = ["aws_lc_rs", "std", "tls12"] }
|
||
serde = { version = "1.0", features = ["derive"] }
|
||
serde_derive = { version = "1.0" }
|
||
serde_json = { version = "1.0" }
|
||
serde_urlencoded = "0.7.1"
|
||
siphasher = "1.0.1"
|
||
sqlx = { version = "0.8.6", features = [
|
||
"chrono",
|
||
"json",
|
||
"migrate",
|
||
"postgres",
|
||
"runtime-tokio",
|
||
"tls-native-tls",
|
||
"uuid",
|
||
] }
|
||
time = { version = "0.3.36", features = [
|
||
"formatting",
|
||
"macros",
|
||
"parsing",
|
||
"serde",
|
||
] }
|
||
thiserror = { version = "2.0" }
|
||
tokio = { version = "1.51.1", features = ["full"] }
|
||
tokio-util = { version = "0.7", features = ["time"] }
|
||
tower = { version = "0.4.13", features = ["limit", "timeout", "util"] }
|
||
tower-http = { version = "0.5.2", features = ["cors", "decompression-br", "decompression-deflate", "decompression-gzip", "decompression-zstd", "limit", "trace"] }
|
||
tracing = "0.1.44"
|
||
tracing-opentelemetry = "0.23.0"
|
||
tracing-subscriber = { version = "0.3.23", features = ["env-filter", "json"] }
|
||
url = "2.5.0"
|
||
uuid = { version = "1.23.0", features = ["v4", "v5", "v7", "serde"] }
|
||
zstd = "0.13"
|
||
neon = "1"
|
||
quick_cache = "0.6.21"
|
||
ahash = "0.8.11"
|
||
aws-config = { version = "1.1.7", features = ["behavior-version-latest"] }
|
||
aws-sdk-s3 = "1.58.0"
|
||
aws-sdk-dynamodb = "1.55.0"
|
||
aws-smithy-runtime-api = { version = "1.11.5", features = ["client"] }
|
||
aws-smithy-http-client = { version = "1.1.11", features = ["rustls-aws-lc"] }
|
||
mockall = "0.13.0"
|
||
moka = { version = "0.12.15", features = ["sync", "future"] }
|
||
redis = { version = "0.32.7", features = [
|
||
"tokio-comp",
|
||
"cluster",
|
||
"cluster-async",
|
||
"tls-rustls",
|
||
"tls-rustls-webpki-roots",
|
||
"tokio-rustls-comp",
|
||
] }
|
||
regex = "1.11.1"
|
||
fancy-regex = "0.17"
|
||
lz-str = "0.2.1"
|
||
lz4 = "1.28"
|
||
opentelemetry-proto = { version = "0.29.0", features = ["with-serde"] }
|
||
# gzip enables request decompression via accept_compressed. Response
|
||
# compression stays with personinsights-common's AsyncGzipLayer — never call
|
||
# send_compressed: tonic's response-encoding negotiation matches any
|
||
# compiled-in feature once the send set is non-empty, so a single
|
||
# send_compressed(x) server would silently compress with whatever encoding
|
||
# feature unification drags in.
|
||
tonic = { version = "0.12.3", features = ["gzip"] }
|
||
tonic-build = "0.12"
|
||
# Our name for it is `datastore`, so `use datastore::Row` stays — but the crate
|
||
# published upstream is named `clickhouse`, and cargo needs the published name to
|
||
# find it. `package =` is exactly that: our alias, their artifact.
|
||
#
|
||
# Renaming this to a bare `datastore` resolved against a DIFFERENT, unrelated
|
||
# crates.io package whose newest version is 0.1.5, so the requirement could never
|
||
# be met. Cargo answers a version it cannot satisfy by failing the whole
|
||
# WORKSPACE, which is why every cargo invocation here — including the
|
||
# cyclotron-node build the insights-plugin image is made of — exited 101, and why
|
||
# that image has not been buildable since.
|
||
datastore = { package = "clickhouse", version = "0.13.2", features = [
|
||
"uuid",
|
||
"time",
|
||
"inserter",
|
||
"rustls-tls",
|
||
] }
|
||
|
||
# Used for decrypting django encrypted fields
|
||
fernet = "0.2"
|
||
tiktoken-rs = "0.7.0"
|
||
sha2 = "0.10"
|
||
sha1 = "0.10"
|
||
hmac = "0.12"
|
||
testcontainers = "0.27.2"
|
||
|