brz-memcache 0.0.5

Asynchronous memcached client with sharding, failover, and live configuration
Documentation
# brz-memcache

An asynchronous memcached client with text and binary protocols, sharding,
replica failover, L1 caches, and application-supplied live configuration.
Connections and protocol sessions use `brz-net`.

## Fixed configuration

The Rust library name is `brz_memcache`:

```rust
use bytes::Bytes;
use brz_memcache::{CacheNamespaceConf, CacheService, CacheServiceOptions, Memcache};

# async fn example() -> brz_memcache::Result<()> {
let mut config = CacheNamespaceConf::single_master("127.0.0.1:11211".into());
config.slave = vec!["127.0.0.1:11212".into()];
let cache = CacheService::new(config, CacheServiceOptions::default()).await?;
cache.set("example", Bytes::from_static(b"value")).await?;
let value = cache.get("example").await?;
# Ok(())
# }
```

`CacheService::single(endpoint)` is the single-master convenience constructor.
`CacheServiceConfig::from_yaml_str` accepts a map of namespace names to native
configuration blocks. The configuration exposes master/slave endpoints, L1
groups, hash/distribution, timeouts, writeback expiration, and explicit
`update_slave_l1`, `local_affinity`, and `backend_no_storage` booleans.

## Live configuration

Implement `CacheServiceConfigSource` in the application or an adapter:

- `load()` returns the initial `CacheNamespaceConf`.
- `subscribe(callback)` registers updates and returns a `SubscriptionHandle`.
  Replay the current configuration when subscribing to avoid losing changes
  between `load` and `subscribe`; deliver later updates in source order.
- The handle's cancellation closure unregisters the callback.

Pass the source to `CacheService::new_live(Arc::new(source), options)`. Live
configuration is available with default features; `service` remains an empty
compatibility feature. The client retains the source and subscription until
the final client clone is dropped. Equal configurations skip rebuilding;
invalid updates retain the last working topology. Concurrent callbacks are
serialized when applying the topology. The client does not poll configuration.

## Infrastructure adapters

The client has no dependency on `discovery`, Vintage, or a mesh registry.
The local `discovery` crate's optional `memcache` feature owns these adapters:

- `vintage_memcache::VintageCacheServiceConfigSource`: shared group polling,
  per-namespace updates, and subscription cleanup.
- `memcache_config::CacheServiceConfig`: legacy YAML conversion, including
  `crc32` normalization and legacy flag bits.
- `memcache_mesh::MeshConfig`: registry-file endpoint resolution and `connect`.

Replace `CacheService::from_vintage` with the adapter plus `new_live`, and
`CacheService::mesh_with_config` with `MeshConfig::connect(options)`.
For legacy YAML, use the discovery parser: the native parser ignores unknown
fields and does **not** interpret the old `flag` field. Existing sharding
algorithms, including hash aliases and `fishermen`, remain unchanged.

## Validation

```sh
cargo fmt --all -- --check
cargo test --all-features
cargo clippy --workspace --all-targets --all-features -- -D warnings
```

Tests use local protocol servers. The `metrics` feature enables physical-access
metrics through `brz-metrics`.

## Releases

CI runs formatting, Clippy, and tests on pushes and pull requests. To publish,
open **Actions → Publish → Run workflow** on `main`. Leave `retry_tag` empty
to create the next `v0.0.x` release. The workflow validates the package, commits
the version, pushes the commit and tag atomically, and publishes to crates.io
using the organization secret `CARGO_REGISTRY_TOKEN`.

If uploading fails after the tag was pushed, retry with that existing tag.
Normal pushes do not publish. Historical tags retain their original package
metadata; use new release tags for registry packages.

Licensed under MIT OR Apache-2.0.

## Crate naming

The package name is `brz-memcache`; the Rust library name is `brz_memcache`.
Use `brz_memcache::...` in Rust code. This replaces the previous `memcache`
library name. Existing explicit dependency aliases remain supported.

```toml
[dependencies]
brz-memcache = "0.0.5"
```