fix(workbench-runtime): ensure session read indexes

This commit is contained in:
lyon
2026-06-22 08:34:40 +08:00
parent 74395d0582
commit 94e77dab1f
+44 -12
View File
@@ -34,6 +34,12 @@ type Server struct {
mux *http.ServeMux
}
var workbenchRuntimeReadIndexes = []string{
"CREATE INDEX IF NOT EXISTS idx_workbench_sessions_updated ON workbench_sessions(updated_at DESC, session_id)",
"CREATE INDEX IF NOT EXISTS idx_workbench_sessions_owner_updated ON workbench_sessions(owner_user_id, updated_at DESC, session_id)",
"CREATE INDEX IF NOT EXISTS idx_workbench_sessions_status_updated ON workbench_sessions(status, updated_at DESC, session_id)",
}
type factQuery struct {
Families []string `json:"families"`
FactFamilies []string `json:"factFamilies"`
@@ -120,6 +126,9 @@ func Run(ctx context.Context) error {
db.SetMaxOpenConns(config.PoolMax)
db.SetMaxIdleConns(config.PoolMax)
}
if err := ensureWorkbenchRuntimeReadIndexes(ctx, db); err != nil {
return err
}
server := NewServer(config, db)
httpServer := &http.Server{Addr: config.Addr, Handler: server.otelHTTPHandler(server.mux), ReadHeaderTimeout: 5 * time.Second}
errCh := make(chan error, 1)
@@ -142,6 +151,17 @@ func Run(ctx context.Context) error {
return httpServer.Shutdown(shutdownCtx)
}
func ensureWorkbenchRuntimeReadIndexes(ctx context.Context, db *sql.DB) error {
ensureCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
for _, statement := range workbenchRuntimeReadIndexes {
if _, err := db.ExecContext(ensureCtx, statement); err != nil {
return fmt.Errorf("ensure workbench runtime read index: %w", err)
}
}
return nil
}
func NewServer(config Config, db *sql.DB) *Server {
server := &Server{config: config, db: db, mux: http.NewServeMux()}
server.routes()
@@ -474,12 +494,7 @@ func (s *Server) queryFactRows(ctx context.Context, table string, jsonColumn str
func (s *Server) queryJSONColumn(ctx context.Context, stage string, table string, sqlText string, args []any) ([]any, error) {
result := []any{}
err := s.withOtelInternalSpan(ctx, stage, map[string]any{
"db.system": "postgresql",
"db.operation.name": "SELECT",
"db.sql.table": table,
"db.query.arg_count": int64(len(args)),
}, func(spanCtx context.Context) error {
err := s.withOtelInternalSpan(ctx, stage, s.dbQueryAttrs(table, len(args), nil), func(spanCtx context.Context) error {
rows, err := s.db.QueryContext(spanCtx, sqlText, args...)
if err != nil {
return err
@@ -503,14 +518,31 @@ func (s *Server) queryJSONColumn(ctx context.Context, stage string, table string
return result, nil
}
func (s *Server) dbQueryAttrs(table string, argCount int, extra map[string]any) map[string]any {
stats := s.db.Stats()
attrs := map[string]any{
"db.system": "postgresql",
"db.operation.name": "SELECT",
"db.sql.table": table,
"db.query.arg_count": int64(argCount),
"db.pool.max_open": int64(s.config.PoolMax),
"db.pool.open_connections": int64(stats.OpenConnections),
"db.pool.in_use": int64(stats.InUse),
"db.pool.idle": int64(stats.Idle),
"db.pool.wait_count": int64(stats.WaitCount),
"db.pool.wait_duration_ms": stats.WaitDuration.Milliseconds(),
"db.pool.max_idle_closed": int64(stats.MaxIdleClosed),
"db.pool.max_lifetime_closed": int64(stats.MaxLifetimeClosed),
}
for key, value := range extra {
attrs[key] = value
}
return attrs
}
func (s *Server) querySessionSummaries(ctx context.Context, stage string, sqlText string, args []any) ([]any, error) {
result := []any{}
err := s.withOtelInternalSpan(ctx, stage, map[string]any{
"db.system": "postgresql",
"db.operation.name": "SELECT",
"db.sql.table": "workbench_sessions",
"db.query.arg_count": int64(len(args)),
}, func(spanCtx context.Context) error {
err := s.withOtelInternalSpan(ctx, stage, s.dbQueryAttrs("workbench_sessions", len(args), map[string]any{"db.index.expected": "idx_workbench_sessions_owner_updated|idx_workbench_sessions_updated"}), func(spanCtx context.Context) error {
rows, err := s.db.QueryContext(spanCtx, sqlText, args...)
if err != nil {
return err