feat(cooler): Cache.Pull returns and removes a value atomically
- Cache.Pull(ctx, key) ([]byte, bool, error), Laravel's Cache::pull
- Redis driver runs GETDEL (Redis 6.2+); memory driver uses otter Compute
with InvalidateOp under the per-key lock; expired keys report not found
- TestPullSmoke over the memory driver and miniredis, ExampleCache_Pull
- README and docs/services/caching.md ("One-time values")
This commit is contained in:
@@ -48,6 +48,36 @@ func ExampleFromApp() {
|
||||
// Output: [Hello Summer] 1
|
||||
}
|
||||
|
||||
func ExampleCache_Pull() {
|
||||
// A one-time code: one request stores it with a short TTL, the request
|
||||
// that redeems it pulls it, and a second redemption finds nothing.
|
||||
cache, err := cooler.NewMemoryCache("acme:", cooler.DefaultMaxEntries)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
ctx := context.Background()
|
||||
if err := cache.Set(ctx, "signin:4f9c", []byte(`{"user_id":7}`), 5*time.Minute); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
for range 2 {
|
||||
payload, ok, err := cache.Pull(ctx, "signin:4f9c")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
fmt.Println("unknown, expired or already used")
|
||||
continue
|
||||
}
|
||||
fmt.Println(string(payload))
|
||||
}
|
||||
// Output:
|
||||
// {"user_id":7}
|
||||
// unknown, expired or already used
|
||||
}
|
||||
|
||||
// Article is a blog's article model.
|
||||
type Article struct {
|
||||
Slug string
|
||||
|
||||
Reference in New Issue
Block a user