Files
go-redis-inventory/agents.md
T
2026-07-03 18:13:11 +02:00

3.5 KiB

go-redis-inventory — agents map

Redis-backed inventory + reservation service. Tracks stock levels and runs atomic reservation operations via Lua scripts; also consumes an inventory_changed pub/sub channel to mirror upstream changes.

Where to start

  • README.md — start here, it has the high-level intent.
  • pkg/inventory/types.go — all the data structures (InventoryItem, InventoryReference, CartReserveRequest, …).
  • pkg/inventory/redis_service.go — basic get / batch get / reserve path
    • the Lua scripts (reserveScript, reservationCheck).
  • pkg/inventory/redis_reservation_service.go — cart-shaped reservations with release/availability semantics + corresponding _test.go.
  • pkg/inventory/listener.goInventoryChangeListener on the inventory_changed pub/sub channel.
  • pkg/inventory/adapter.goReservationPolicyAdapter bridging to platform/inventory.ReservationPolicy.

Architecture

  • Two responsibilities, one process: (1) hold and serve inventory state; (2) mirror upstream changes via pub/sub.
  • Atomicity: reservation idempotency and TTL semantics come from Lua scripts embedded here. The scripts are the seam — if they change, the test in redis_reservation_service_test.go is the contract.
  • Adapter: the ReservationPolicyAdapter is the seam to platform/inventory. Two adapters (this service and any other downstream caller) is what makes it a real seam, not a hypothetical one.

Important files by area

Area File
Domain model pkg/inventory/types.go
Core service pkg/inventory/redis_service.go
Reservation service (cart) pkg/inventory/redis_reservation_service.go
Pub/sub listener pkg/inventory/listener.go
Platform adapter pkg/inventory/adapter.go
Reservation tests pkg/inventory/redis_reservation_service_test.go

Cross-project seams

  • platform/inventory: implements ReservationPolicy via the adapter.
  • go-cart-actor: consumes reservations through that adapter.
  • Redis pub/sub: receives inventory_changed events.

Improvement suggestions

  • types.go carries mixed concernsInventoryItem (storage) sits next to CartReserveRequest (request). Split into types/ (storage-level) and types/cart.go (request) so callers can depend on only the slice they need.
  • Two reservation services: redis_service.go has its own reserve, redis_reservation_service.go has another, plus a Level type (level.go). The relationship between them isn't documented; an architecture paragraph at the top of the package would help (doc.go or pkg/inventory/README.md).
  • listener.go is single-channel — it consumes only inventory_changed. If more channels need the same lifecycle (reconnect, dedupe, back-off), factor out a tiny pubsub.Consumer and let the listener wrap it.
  • Lua scripts live inside Go source. Promote them to .lua files, registered via //go:embed — that makes them version-controlled and testable independently of the Go code.
  • No config validation. A malformed REDIS_URL/CHANNEL boots and fails at first call. Fail fast in main.go with explicit error messages.