litellm/litellm-rust/crates
yujonglee 574fcea691
fix(redis): share one native circuit breaker between RedisCache and the Rust stores (#50473)
* fix(redis): share one native circuit breaker between RedisCache and the Rust stores

RedisCache and the native Redis client each kept their own breaker, so once
the cache learned the coordination Redis was wedged, a spend-counter write
through the native store still paid a full socket timeout. Every Redis target
now has one Rust breaker, looked up by NativeRedisBreaker.shared and injected
into both the RedisCache guard and the native client. The Python FSM is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(rust): cargo fmt the shared breaker

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(redis): close the breaker when the recovery probe gets a Redis reply error

A command error such as WRONGTYPE means Redis answered, but the probe was left
unsettled and its drop reopened the breaker for another recovery timeout. Both
the RedisCache guard and the native client now settle such a probe as a success.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(redis): pass a NativeRedisBreaker and isolate the shared breaker per test

The sensitive routing test still passed RedisBreakerSettings as the store breaker, and the session affinity fixture reused one Redis URL, so a breaker an earlier test opened leaked into the next. Also make the RUF043 match pattern raw.

* fix(redis): key the shared breaker by server and close the three audit gaps

The breaker registry now keys on the Redis server (host and port, unix socket,
cluster node set or sentinel service) instead of the full connection target, so
caches that differ only in db, credentials or url spelling share one breaker.

A READONLY reply from a replica mid-failover no longer counts as Redis answering,
so it can't reset a run of failures. A new RedisCache refreshes the breaker state
gauge, which the deleted Python breaker did at construction. A shared native client
is only reused by a store that passes the same breaker.

* refactor(redis): split redis-types into modules and drop redundant pyo3 attribute annotations

lib.rs now only declares modules and re-exports, with resolution, target, tls,
auth and endpoint each in their own file. Derived FromPyObject already reads a
struct field as the attribute of the same name, so #[pyo3(attribute)] on the
breaker and store settings did nothing.

* refactor(redis): drop redundant pyo3 attribute annotations in the stores and let PyO3 build the cooldown snapshot

Derived FromPyObject already reads each field as the attribute of the same name.
The cooldown snapshot returns an IndexMap, which PyO3 turns into the same dict in
the same order.

* refactor(redis): return a HashMap from the three memory-tier snapshots

The snapshots read cache-memory's HashMap, so there is no order to keep.
PyO3 builds the same dict from a std HashMap, which replaces the hand-written
PyDict loops in the spend counter and router usage stores and the IndexMap in
the cooldown store. The rate-limit slot registry keeps IndexMap because it
hands back a Python dict in the order Python wrote it.

* refactor(redis): share Redis breakers and clients through one RedisHosts per host

redis-connect's RedisHosts now owns the per-server breaker and the shared clients
that python-bridge kept in two process-wide statics. A client takes breaker
settings and admits through its server's breaker, so no caller can pair a client
with a breaker of its own, and clients are keyed by Resolution alone. This drops
RedisClient::guarded_by and Breaker::same.

python-bridge keeps one RedisHosts per process and calls it with the GIL released.
The gateway builds one per connect, so its coordination and response cache on the
same server now share a breaker. RedisStoreSettings.breaker is back to breaker
settings, as on main.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 17:50:06 +09:00
..
auth refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
auth-aws fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
auth-azure fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
auth-gcp fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
auth-types fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
cache refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
cache-azure-blob refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
cache-disk refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
cache-gcs fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
cache-memory feat(redis): extend the native Redis foundation for the store families (#50169) 2026-11-06 12:30:07 +09:00
cache-qdrant-semantic refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
cache-response refactor(cache): remove experimental Redis and v2 caches (#50005) 2026-11-04 04:54:08 +00:00
cache-s3 fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
cache-testing refactor(rust): align the cache crates with Python and wire every native backend (#42530) 2026-09-22 13:13:02 -07:00
callbacks-legacy-python fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
circuit-breaker fix(redis): share one native circuit breaker between RedisCache and the Rust stores (#50473) 2026-11-07 17:50:06 +09:00
config feat(redis): extend the native Redis foundation for the store families (#50169) 2026-11-06 12:30:07 +09:00
core-utils fix(anthropic): map pause_turn and return refusal explanations on chat and responses (#49192) 2026-10-31 02:53:59 -07:00
coroutine refactor(rust-bridge): return an unstarted Execution from native entrypoints and drive it in Python (#46299) 2026-10-14 17:50:44 -07:00
cost feat(model-catalog): add fedramp_uplift_multiplier (#49950) 2026-11-03 14:55:51 -08:00
db feat(db): add typed daily end-user spend upsert (#48237) 2026-10-26 17:05:08 -07:00
db-testing feat(rust): add redis-client crate for standalone Redis (#48269) 2026-10-26 18:41:46 -07:00
error refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
framer refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
gateway fix(redis): share one native circuit breaker between RedisCache and the Rust stores (#50473) 2026-11-07 17:50:06 +09:00
gateway-auth refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
gateway-forward feat(gateway): forward HTTP requests to the Python proxy (#49604) 2026-11-05 19:03:34 +00:00
gateway-inference refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
gateway-management refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
gateway-mcp refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
gateway-ui refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
host fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
host-http fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
host-native fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
host-python feat(redis): extend the native Redis foundation for the store families (#50169) 2026-11-06 12:30:07 +09:00
http fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
inference fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
inference-chat fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
inference-messages fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
inference-ocr fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
inference-responses fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
inference-testing refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
inference-transcription feat(rust): one typed decline from core up to each host (#47772) 2026-10-28 09:22:11 -07:00
litellm refactor(rust): expand logging and test coverage across gateway and Anthropic messages (#43295) 2026-09-26 08:04:19 +00:00
llms fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
llms-types fix(messages): make rust messages copy python messages behaviour (#49611) 2026-11-02 21:02:52 -08:00
model-catalog feat(model-catalog): add fedramp_uplift_multiplier (#49950) 2026-11-03 14:55:51 -08:00
model-catalog-refresh refactor(model-catalog): parse, lower and validate the catalog into typed prices (#48853) 2026-10-28 18:24:40 -07:00
python-bridge fix(redis): share one native circuit breaker between RedisCache and the Rust stores (#50473) 2026-11-07 17:50:06 +09:00
python-compat feat(redis): extend the native Redis foundation for the store families (#50169) 2026-11-06 12:30:07 +09:00
redis-client fix(redis): share one native circuit breaker between RedisCache and the Rust stores (#50473) 2026-11-07 17:50:06 +09:00
redis-connect fix(redis): share one native circuit breaker between RedisCache and the Rust stores (#50473) 2026-11-07 17:50:06 +09:00
redis-resolve feat(redis): extend the native Redis foundation for the store families (#50169) 2026-11-06 12:30:07 +09:00
redis-store feat(redis): serve the proxy's common Redis call with Rust stores (#50170) 2026-11-06 06:01:11 +00:00
redis-testing feat(redis): extend the native Redis foundation for the store families (#50169) 2026-11-06 12:30:07 +09:00
redis-types fix(redis): share one native circuit breaker between RedisCache and the Rust stores (#50473) 2026-11-07 17:50:06 +09:00
router fix(vertex_ai)!: send the caller's anthropic-version in the Vertex Claude /v1/messages body, not the header (#48814) 2026-10-28 18:06:58 -07:00
router-core fix(router): pin /v1/responses requests for prompt caching affinity (#50321) 2026-11-06 12:56:54 -08:00
router-types refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
secret-value fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
secrets refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
secrets-aws fix(auth): align cloud credential loading and expiry with the Python SDKs (#49589) 2026-11-05 07:18:19 +09:00
secrets-azure refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
secrets-cyberark refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
secrets-google refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
secrets-hashicorp refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
secrets-types refactor(rust): extract SecretValue and use it for Redis credentials (#49186) 2026-10-30 11:31:04 -07:00
spend-clickhouse refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
storage-clickhouse refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
testkit refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
token-counter refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
token-counter-fast refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
token-counter-huggingface refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
token-counter-tiktoken refactor(rust): adopt one error discipline across litellm-rust with source chains and Report (#48042) 2026-10-28 09:22:11 -07:00
tracing feat(rust): add structured route lifecycle tracing (#43466) 2026-09-27 19:18:58 -07:00