fix: replace in-memory ID counter with atomic database counter

Replace the in-memory nextID counter with an atomic database-backed
counter using the issue_counters table. This fixes race conditions
when multiple processes create issues concurrently.

Changes:
- Add issue_counters table with atomic INSERT...ON CONFLICT pattern
- Remove in-memory nextID field and sync.Mutex from SQLiteStorage
- Implement getNextIDForPrefix() for atomic ID generation
- Update CreateIssue() to use database counter instead of memory
- Update RemapCollisions() to use database counter for collision resolution
- Clean up old planning and bug documentation files

Fixes the multi-process ID generation race condition tested in
cmd/bd/race_test.go.
This commit is contained in:
v4rgas
2025-10-13 19:29:29 -03:00
committed by Steve Yegge
parent d85ff17f40
commit 20e3235435
6 changed files with 60 additions and 550 deletions

View File

@@ -232,15 +232,16 @@ func RemapCollisions(ctx context.Context, s *SQLiteStorage, collisions []*Collis
for _, collision := range collisions {
oldID := collision.ID
// Allocate new ID
s.idMu.Lock()
// Allocate new ID using atomic counter
prefix, err := s.GetConfig(ctx, "issue_prefix")
if err != nil || prefix == "" {
prefix = "bd"
}
newID := fmt.Sprintf("%s-%d", prefix, s.nextID)
s.nextID++
s.idMu.Unlock()
nextID, err := s.getNextIDForPrefix(ctx, prefix)
if err != nil {
return nil, fmt.Errorf("failed to generate new ID for collision %s: %w", oldID, err)
}
newID := fmt.Sprintf("%s-%d", prefix, nextID)
// Record mapping
idMapping[oldID] = newID