Some checks failed
CI / Check for .beads changes (push) Has been skipped
CI / Check embedded formulas (push) Successful in 20s
CI / Test (push) Failing after 1m23s
CI / Lint (push) Successful in 17s
CI / Integration Tests (push) Successful in 1m1s
CI / Coverage Report (push) Has been skipped
Windows CI / Windows Build and Unit Tests (push) Has been cancelled
Mail operations were taking 30+ seconds due to beads daemon auto-import cycles. Each bd query would wait up to 5 seconds for auto-import to complete, and with 3+ queries per inbox check, this added up. The fix bypasses the daemon by passing --no-daemon to all bd commands in the mail package. This is appropriate because: - Mail queries are read-heavy and don't benefit from daemon caching - Direct SQLite access is faster for one-off queries - Avoids daemon auto-import/export cycle delays Performance improvement: 31+ seconds → 1.2 seconds Fixes: hq-b1o08 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
69 lines
1.9 KiB
Go
69 lines
1.9 KiB
Go
package mail
|
|
|
|
import (
|
|
"bytes"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
// bdError represents an error from running a bd command.
|
|
// It wraps the underlying error and includes the stderr output for inspection.
|
|
type bdError struct {
|
|
Err error
|
|
Stderr string
|
|
}
|
|
|
|
// Error implements the error interface.
|
|
func (e *bdError) Error() string {
|
|
if e.Stderr != "" {
|
|
return e.Stderr
|
|
}
|
|
if e.Err != nil {
|
|
return e.Err.Error()
|
|
}
|
|
return "unknown bd error"
|
|
}
|
|
|
|
// Unwrap returns the underlying error for errors.Is/As compatibility.
|
|
func (e *bdError) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
// ContainsError checks if the stderr message contains the given substring.
|
|
func (e *bdError) ContainsError(substr string) bool {
|
|
return strings.Contains(e.Stderr, substr)
|
|
}
|
|
|
|
// runBdCommand executes a bd command with proper environment setup.
|
|
// workDir is the directory to run the command in.
|
|
// beadsDir is the BEADS_DIR environment variable value.
|
|
// extraEnv contains additional environment variables to set (e.g., "BD_IDENTITY=...").
|
|
// Returns stdout bytes on success, or a *bdError on failure.
|
|
//
|
|
// Uses --no-daemon to bypass the beads daemon for direct database access.
|
|
// This avoids 5+ second delays caused by daemon auto-import cycles (bd-xxxx).
|
|
// Mail operations are read-heavy and don't benefit from daemon caching.
|
|
func runBdCommand(args []string, workDir, beadsDir string, extraEnv ...string) ([]byte, error) {
|
|
// Prepend --no-daemon to avoid daemon auto-import delays
|
|
args = append([]string{"--no-daemon"}, args...)
|
|
cmd := exec.Command("bd", args...) //nolint:gosec // G204: bd is a trusted internal tool
|
|
cmd.Dir = workDir
|
|
|
|
env := append(cmd.Environ(), "BEADS_DIR="+beadsDir)
|
|
env = append(env, extraEnv...)
|
|
cmd.Env = env
|
|
|
|
var stdout, stderr bytes.Buffer
|
|
cmd.Stdout = &stdout
|
|
cmd.Stderr = &stderr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return nil, &bdError{
|
|
Err: err,
|
|
Stderr: strings.TrimSpace(stderr.String()),
|
|
}
|
|
}
|
|
|
|
return stdout.Bytes(), nil
|
|
}
|