Fix bd-1ezg: Prevent import/export from hanging when daemon is running
Root cause: Import and export commands tried to open the database directly while the daemon already held the lock, causing indefinite blocking. Solution: Both commands now explicitly close the daemon connection before opening direct database access, avoiding SQLite lock contention. Changes: - import.go: Close daemon connection and open direct SQLite connection - export.go: Close daemon connection before direct access - Added debug logging to help diagnose similar issues Tests: Existing TestImport and TestExport tests pass
This commit is contained in:
@@ -95,10 +95,18 @@ Output to stdout by default, or use -o flag for file output.`,
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export command doesn't work with daemon - need direct access
|
// Export command requires direct database access for consistent snapshot
|
||||||
|
// If daemon is connected, close it and open direct connection
|
||||||
|
if daemonClient != nil {
|
||||||
|
if os.Getenv("BD_DEBUG") != "" {
|
||||||
|
fmt.Fprintf(os.Stderr, "Debug: export command forcing direct mode (closes daemon connection)\n")
|
||||||
|
}
|
||||||
|
_ = daemonClient.Close()
|
||||||
|
daemonClient = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure we have a direct store connection
|
// Ensure we have a direct store connection
|
||||||
if store == nil {
|
if store == nil {
|
||||||
// Initialize store directly even if daemon is running
|
|
||||||
var err error
|
var err error
|
||||||
if dbPath == "" {
|
if dbPath == "" {
|
||||||
fmt.Fprintf(os.Stderr, "Error: no database path found\n")
|
fmt.Fprintf(os.Stderr, "Error: no database path found\n")
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/steveyegge/beads/internal/storage/sqlite"
|
||||||
"github.com/steveyegge/beads/internal/types"
|
"github.com/steveyegge/beads/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,8 +26,30 @@ Behavior:
|
|||||||
- New issues are created
|
- New issues are created
|
||||||
- Collisions (same ID, different content) are detected and reported
|
- Collisions (same ID, different content) are detected and reported
|
||||||
- Use --dedupe-after to find and merge content duplicates after import
|
- Use --dedupe-after to find and merge content duplicates after import
|
||||||
- Use --dry-run to preview changes without applying them`,
|
- Use --dry-run to preview changes without applying them
|
||||||
|
|
||||||
|
NOTE: Import requires direct database access and does not work with daemon mode.
|
||||||
|
The command automatically uses --no-daemon when executed.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// Import requires direct database access due to complex transaction handling
|
||||||
|
// and collision detection. Force direct mode regardless of daemon state.
|
||||||
|
if daemonClient != nil {
|
||||||
|
if os.Getenv("BD_DEBUG") != "" {
|
||||||
|
fmt.Fprintf(os.Stderr, "Debug: import command forcing direct mode (closes daemon connection)\n")
|
||||||
|
}
|
||||||
|
_ = daemonClient.Close()
|
||||||
|
daemonClient = nil
|
||||||
|
|
||||||
|
// Now initialize direct store
|
||||||
|
var err error
|
||||||
|
store, err = sqlite.New(dbPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: failed to open database: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer func() { _ = store.Close() }()
|
||||||
|
}
|
||||||
|
|
||||||
input, _ := cmd.Flags().GetString("input")
|
input, _ := cmd.Flags().GetString("input")
|
||||||
skipUpdate, _ := cmd.Flags().GetBool("skip-existing")
|
skipUpdate, _ := cmd.Flags().GetBool("skip-existing")
|
||||||
strict, _ := cmd.Flags().GetBool("strict")
|
strict, _ := cmd.Flags().GetBool("strict")
|
||||||
|
|||||||
Reference in New Issue
Block a user