KeiSeiKit-1.0/_primitives/_rust/kei-store/Cargo.toml
Parfii-bot bc7e099697 refactor(v0.22): kei-store AsyncBackend trait + shared tokio runtime (Track B)
Extracts an AsyncBackend trait in kei-store so future GCS/Azure/Bunny
backends implement 5 async fns, not re-invent the sync-over-tokio
bridge. Closes architect P1 + P2 findings.

NEW src/async_backend.rs (189 LOC):
  - trait AsyncBackend with get/put/list/list_recursive/delete/exists
  - AsyncBackendStore<B: AsyncBackend> — generic MemoryStore impl
    (sync-over-async via shared runtime)
  - shared_runtime() -> &'static Runtime via OnceLock
    (multi-thread, 2 workers, enable_io+enable_time)
  - path helpers (validate_rel, short_hash, is_manifest_key) moved
    here as single source of truth

NEW src/s3_cloud/backend.rs (120 LOC):
  - S3AsyncBackend impl of AsyncBackend — 5 async fns using the
    existing aws-sdk-s3::Client

MODIFIED src/s3_cloud/mod.rs (200 → 43 LOC):
  pub type S3CloudStore = AsyncBackendStore<S3AsyncBackend>;
  Thin re-export + inherent new(cfg) constructor.
  Doc-header documents the extension seam: 'adding GCS = impl 5 async fns'.

MODIFIED src/s3_cloud/keys.rs (66 → 40 LOC): compat shim — re-exports
  validate_rel / short_hash / is_manifest_key from async_backend.
  Old call-sites + 4 unit tests unchanged.

Deps: async-trait = 0.1 added under s3 feature; tokio now has
  rt-multi-thread feature too.

FIXES N=2 Store footgun: prior impl created a current_thread Runtime
  per instance — 2 instances in one process = 2 runtimes, block_on
  panic if caller is on another runtime. Shared multi-thread runtime
  via OnceLock means N instances all share 2 workers.

REAL VERIFICATION (agent-pasted):
  cargo check -p kei-store: clean
  cargo check -p kei-store --features s3: clean
  cargo test -p kei-store --release: 10+9+0 = 19 passed
  cargo test -p kei-store --features s3 --release: 38+9+6 = 53 passed
    (+7 vs baseline 46)

Tests added (7):
  async_backend::tests::shared_runtime_is_singleton
  async_backend::tests::validate_rel_rejects_absolute
  async_backend::tests::validate_rel_rejects_parent
  async_backend::tests::short_hash_deterministic
  async_backend::tests::is_manifest_key_matches_format
  s3_cloud::tests::async_backend_shared_runtime_handles_two_store_instances
  s3_cloud::tests::async_backend_runtime_is_multi_thread

Public API preserved: S3CloudStore::new / .branch / .current_branch /
  .key / .backend_name. Factory + integration tests untouched.

Pre-existing: list_inner 38 LOC (moved verbatim from mod.rs, not
  refactored per Core Rule 3).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 21:06:50 +08:00

38 lines
1.3 KiB
TOML

[package]
name = "kei-store"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
description = "Memory-repo backend abstraction — GitHub/Forgejo/Gitea/Filesystem/S3 (v0.21.0)"
[[bin]]
name = "kei-store"
path = "src/main.rs"
[lib]
path = "src/lib.rs"
[features]
# Default: no cloud deps. S3 backend behaves as the v0.14 local-manifest stub
# (gated by KEI_STORE_ALLOW_S3_STUB=1). Users who actually need real S3 / R2 /
# MinIO push opt into the heavier AWS SDK stack by enabling this feature.
default = []
s3 = ["dep:aws-config", "dep:aws-sdk-s3", "dep:aws-credential-types", "dep:tokio", "dep:async-trait"]
[dependencies]
clap = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
anyhow = "1"
toml = "0.8"
git2 = { version = "0.19", default-features = false }
# v0.21 — optional cloud stack behind `s3` feature.
aws-config = { version = "1", default-features = false, features = ["behavior-version-latest", "rustls", "rt-tokio"], optional = true }
aws-sdk-s3 = { version = "1", default-features = false, features = ["behavior-version-latest", "rustls", "rt-tokio"], optional = true }
aws-credential-types = { version = "1", optional = true }
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"], optional = true }
async-trait = { version = "0.1", optional = true }
[dev-dependencies]
tempfile = "3"