Add CI workflow, README, CLAUDE.md, AGENTS.md, and .cursorrules
All checks were successful
CI / test (push) Successful in 51s
All checks were successful
CI / test (push) Successful in 51s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
55
.cursorrules
Normal file
55
.cursorrules
Normal file
@@ -0,0 +1,55 @@
|
||||
You are working on `git.codelab.vc/pkg/dbx`, a Go PostgreSQL cluster library built on pgx/v5.
|
||||
|
||||
## Architecture
|
||||
|
||||
- Cluster manages master + replicas with method-based routing (no SQL parsing)
|
||||
- Write ops (Exec, Query, QueryRow, Begin, BeginTx, CopyFrom, SendBatch) → master
|
||||
- Read ops (ReadQuery, ReadQueryRow) → replicas with master fallback
|
||||
- Retry with exponential backoff + jitter, iterates nodes then backs off
|
||||
- Round-robin balancer skips unhealthy nodes
|
||||
- Background health checker pings all nodes on interval
|
||||
- RunTx — panic-safe transaction wrapper (recover → rollback → re-panic)
|
||||
- InjectQuerier/ExtractQuerier — context-based Querier for service layers
|
||||
|
||||
## Package structure
|
||||
|
||||
- `dbx` (root) — Cluster, Node, Balancer, retry, health, errors, tx, config, options
|
||||
- `dbx.go` — interfaces: Querier, DB, Logger, MetricsHook
|
||||
- `cluster.go` — Cluster routing and query execution
|
||||
- `node.go` — Node wrapping pgxpool.Pool with health state
|
||||
- `balancer.go` — Balancer interface + RoundRobinBalancer
|
||||
- `retry.go` — retrier with backoff and node fallback
|
||||
- `health.go` — background health checker goroutine
|
||||
- `tx.go` — RunTx, RunTxOptions, InjectQuerier, ExtractQuerier
|
||||
- `errors.go` — IsRetryable, IsConnectionError, IsConstraintViolation, PgErrorCode
|
||||
- `config.go` — Config, NodeConfig, PoolConfig, RetryConfig, HealthCheckConfig
|
||||
- `options.go` — functional options (WithLogger, WithMetrics, WithRetry, WithHealthCheck)
|
||||
- `dbxtest/` — test helpers: NewTestCluster, TestLogger
|
||||
|
||||
## Code conventions
|
||||
|
||||
- Struct-based Config with defaults() method for zero-value defaults
|
||||
- Functional options (Option func(*Config)) used via ApplyOptions
|
||||
- stdlib only testing — no testify, no gomock
|
||||
- Thread safety with atomic.Bool (Node.healthy, Cluster.closed)
|
||||
- dbxtest.NewTestCluster skips on unreachable DB, auto-closes via t.Cleanup
|
||||
- Sentinel errors: ErrNoHealthyNode, ErrClusterClosed, ErrRetryExhausted
|
||||
- retryError multi-unwrap for errors.Is compatibility
|
||||
|
||||
## When writing new code
|
||||
|
||||
- New node type → add to Cluster struct, Config, connect in NewCluster, add to `all` for health checking
|
||||
- New balancer → implement Balancer interface, check IsHealthy(), return nil if no suitable node
|
||||
- New retry logic → provide RetryConfig.RetryableErrors or extend IsRetryable()
|
||||
- New metrics hook → add field to MetricsHook, nil-check before calling
|
||||
- Close() is required — leaking a Cluster leaks goroutines and connections
|
||||
- No SQL parsing — routing is method-based, Exec with SELECT still goes to master
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
go build ./... # compile
|
||||
go test ./... # test
|
||||
go test -race ./... # test with race detector
|
||||
go vet ./... # static analysis
|
||||
```
|
||||
Reference in New Issue
Block a user