feat: add independent platform modules and multi-provider storage

This commit is contained in:
2026-09-23 14:51:14 +08:00
parent f91034477b
commit 208a9c3fbd
57 changed files with 4890 additions and 48 deletions

View File

@@ -17,12 +17,13 @@ import (
)
type IdempotencyConfig struct {
TTL time.Duration `json:"ttl"`
MaxEntries int `json:"maxEntries"`
MaxBytes int `json:"maxBytes"`
MaxRequestBytes int64 `json:"maxRequestBytes"`
MaxResponseBytes int `json:"maxResponseBytes"`
MaxInFlight int `json:"maxInFlight"`
Store IdempotencyStore `json:"-"` // Optional shared store; nil keeps local behavior.
TTL time.Duration `json:"ttl"`
MaxEntries int `json:"maxEntries"`
MaxBytes int `json:"maxBytes"`
MaxRequestBytes int64 `json:"maxRequestBytes"`
MaxResponseBytes int `json:"maxResponseBytes"`
MaxInFlight int `json:"maxInFlight"`
// Scope must return a server-verified tenant/user identity. Register auth
// before this middleware. Client-provided identity is not authorization.
Scope func(*httpx.Context) (string, error) `json:"-"`
@@ -53,6 +54,9 @@ func NewIdempotency(cfg IdempotencyConfig) (*Idempotency, error) {
if cfg.TTL == 0 {
cfg.TTL = 10 * time.Minute
}
if cfg.Store != nil && cfg.TTL > 30*24*time.Hour {
return nil, errors.New("middleware: shared idempotency TTL exceeds 30d")
}
if cfg.MaxEntries == 0 {
cfg.MaxEntries = 256
}
@@ -125,6 +129,9 @@ func (i *Idempotency) Middleware() httpx.Middleware {
copy(fingerprint[:], hash.Sum(nil))
namespace, _ := json.Marshal([]string{scope, key})
id := sha256.Sum256(namespace)
if i.config.Store != nil {
return i.shared(c, next, id, fingerprint)
}
i.mu.Lock()
now := i.now()
for k, v := range i.items {