Phase 0 -- Hardening: - Fix SQLITE_BUSY under concurrent writes by setting SetMaxOpenConns(1) and PRAGMA busy_timeout=5000 - Add comprehensive tests: concurrent read/write (10 goroutines), edge cases (unicode, null bytes, SQL injection, long keys), error paths (closed store, invalid paths, corrupt files), group isolation, upsert verification, WAL mode verification, ErrNotFound wrapping - Add benchmarks: Set, Get, GetAll (10K keys), file-backed Set Phase 1 -- TTL Support: - Add expires_at nullable column with schema migration for pre-TTL DBs - SetWithTTL(group, key, value, duration) stores keys that auto-expire - Lazy deletion on Get for expired keys - Background purge goroutine (configurable interval, default 60s) - Public PurgeExpired() method for manual cleanup - Count, GetAll, Render all exclude expired entries - Set clears TTL when overwriting a TTL key Coverage: 73.1% -> 90.9% (48 tests, 0 races) Co-Authored-By: Charon <developers@lethean.io>
2.2 KiB
2.2 KiB
TODO.md -- go-store
Dispatched from core/go orchestration. Pick up tasks in order.
Phase 0: Hardening & Test Coverage
- Expand test coverage -- concurrent Set/Get with 10 goroutines (race test), Render() with invalid template syntax, Render() with missing template vars, Get() on non-existent group vs non-existent key, DeleteGroup() then verify GetAll() returns empty, Count() after bulk inserts, :memory: vs file-backed store, WAL mode verification. Coverage: 73.1% -> 90.9%.
- Edge cases -- empty key, empty value, empty group, very long key (10K chars), binary-ish value (null bytes), Unicode keys and values, CJK, Arabic, SQL injection attempts, special characters.
- Benchmark -- BenchmarkSet, BenchmarkGet, BenchmarkGetAll with 10K keys, BenchmarkSet_FileBacked.
go vet ./...clean -- no warnings.- Concurrency fix -- Added
db.SetMaxOpenConns(1)andPRAGMA busy_timeout=5000to prevent SQLITE_BUSY errors under concurrent writes.
Phase 1: TTL Support
- Add optional expiry timestamp for keys (
expires_at INTEGERcolumn) - Background goroutine to purge expired entries (configurable interval, default 60s)
SetWithTTL(group, key, value, duration)API- Lazy expiry check on
Getas fallback PurgeExpired()public method for manual purgeCount,GetAll,Renderexclude expired entries- Schema migration for pre-TTL databases (ALTER TABLE ADD COLUMN)
- Tests for all TTL functionality including concurrent TTL access
Phase 2: Namespace Isolation
- Group-based access control for multi-tenant use
- Namespace prefixing to prevent key collisions across tenants
- Per-namespace quota limits (max keys, max total size)
Phase 3: Event Hooks
- Notify on
Set/Deletefor reactive patterns - Channel-based subscription:
Watch(group, key) <-chan Event - Support wildcard watches (
Watch(group, "*")) - Integration hook for go-ws to broadcast store changes via WebSocket
Workflow
- Virgil in core/go writes tasks here after research
- This repo's dedicated session picks up tasks in phase order
- Mark
[x]when done, note commit hash