5 Commits
Author SHA1 Message Date
zeekay 22c14df4fa refactor: pool manager → dbx, base re-exports
PoolManager now lives in hanzoai/dbx v1.13.0 (canonical home).
base/plugins/platform/db_pool.go is a thin re-export wrapper.

Stack: dbx (pool) → orm (models) → base (platform)
One and only one way: dbx.NewPoolManager()
2026-03-02 14:14:26 -07:00
zeekay d02a70442d migrate: pocketbase/dbx → hanzoai/dbx v1.12.0
Drop-in replacement — same API, same package name (dbx).
75 Go files updated. Zero pocketbase references in imports.
2026-03-02 13:54:55 -07:00
zeekay 44a531c54a perf: sharded RWMutex pool manager, 10K+ org scale
Optimizations from lux/metrics patterns:
- 16 shards with RWMutex (RLock for cache hits, Lock for misses)
- Cache-line padded PoolStats (no false sharing across cores)
- Two-phase eviction (find under lock, close without lock)
- FNV hash for shard selection

Benchmarks (M1 Max, -cpu=1,4,10):
  CacheHit:      118 ns (0 alloc) — scales flat across CPUs
  CacheMiss:     78 µs — dominated by SQLite open, no lock contention
  ConcurrentHit: 1.8 µs at 4 CPUs (1.3x faster than single)
  ReadWrite:     12 µs — stable across CPU counts (WAL is the bottleneck)
  ManyOrgs:      1.1 µs at 10 CPUs (6.4x faster than single) ← sharding pays off

At 10,000 org scale with eviction pressure, 10-CPU throughput
is 3.1M ops/sec with only 465 B/op.

6 tests pass: get/release, LRU eviction, no-evict-in-use,
100-goroutine concurrent access, close, data persistence.
2026-03-02 13:37:40 -07:00
zeekay 917cc4a634 fix: db pool config struct, tests + benchmarks
- DBPoolConfig with tunable ReadConns, ReadIdleConns, MaxPools
- Fixed openPool to use filepath.Dir (was buggy string slicing)
- 6 tests: get/release, LRU eviction, no-evict-in-use, concurrent
  access (100 goroutines), close, data persistence across reopen
- 5 benchmarks: cache hit (22ns), miss (79us), concurrent read
  (6.4us), read/write mix (17us), 500-org eviction pressure (5.9us)
- PoolStats for monitoring (hits, misses, evictions, opens, errors)
2026-03-02 12:42:15 -07:00
zeekay 425d008f4b feat: per-org/per-user SQLite pool manager + request middleware
DBPoolManager: LRU cache of dual-pool SQLite connections (read pool
with 20 conns + write pool with 1 conn per database file). Evicts
least-recently-used pools when capacity is reached.

platformOrgDBResolver middleware (priority loadAuthToken+4):
- Reads X-Org-Id and X-User-Id headers (set by upstream middleware)
- Resolves or auto-provisions the org/user SQLite file
- Stores DBPool in request context via re.Set("orgDB"/"userDB")
- Services are fully stateless — any instance serves any org/user

File layout:
  {DataDir}/orgs/{orgId}/org.db
  {DataDir}/orgs/{orgId}/users/{userId}/data.db

Activated when OrgIsolation="sqlite" in PlatformConfig.
2026-03-02 11:38:31 -07:00