more
Build and Publish / BuildAndDeployArm64 (push) Failing after 5s
Build and Publish / BuildAndDeployAmd64 (push) Has been cancelled

This commit is contained in:
2026-06-21 23:47:53 +02:00
parent 9d420c43fa
commit a1f0bad972
5 changed files with 38 additions and 24 deletions
+14 -14
View File
@@ -14,19 +14,23 @@ import (
"bufio"
"encoding/json"
"errors"
"hash/fnv"
"os"
"sync"
)
// lockShards bounds the per-key lock memory: keys hash into a fixed set of
// mutexes rather than a map that grows with every distinct key ever seen. Two
// unrelated keys that collide on a shard serialise occasionally — harmless.
const lockShards = 256
// Store maps an idempotency key to a result id (e.g. an order id), cached in
// memory and persisted to an append-only file.
type Store struct {
mu sync.Mutex
m map[string]uint64
f *os.File
klMu sync.Mutex
keyLocks map[string]*sync.Mutex
mu sync.Mutex
m map[string]uint64
f *os.File
locks [lockShards]sync.Mutex
}
type record struct {
@@ -62,7 +66,7 @@ func Open(path string) (*Store, error) {
if err != nil {
return nil, err
}
return &Store{m: m, f: f, keyLocks: map[string]*sync.Mutex{}}, nil
return &Store{m: m, f: f}, nil
}
// Get returns the recorded id for key and whether it was present.
@@ -103,13 +107,9 @@ func (s *Store) Lock(key string) func() {
if key == "" {
return func() {}
}
s.klMu.Lock()
mu, ok := s.keyLocks[key]
if !ok {
mu = &sync.Mutex{}
s.keyLocks[key] = mu
}
s.klMu.Unlock()
h := fnv.New32a()
_, _ = h.Write([]byte(key))
mu := &s.locks[h.Sum32()%lockShards]
mu.Lock()
return mu.Unlock
}