diff --git a/go/internal/api/routes/admin.go b/go/internal/api/routes/admin.go index 840b629..8260e41 100644 --- a/go/internal/api/routes/admin.go +++ b/go/internal/api/routes/admin.go @@ -2,6 +2,7 @@ package routes import ( + "context" "encoding/json" "fmt" "net/http" @@ -108,15 +109,21 @@ func (aa *AdminAPI) Backup(w http.ResponseWriter, r *http.Request) { return } - // 3. Redis BGSAVE (async) + // 3. Redis BGSAVE (fire-and-forget) exec.Command("redis-cli", "BGSAVE").Run() - // 4. Tar LanceDB directories - if err := exec.Command("tar", "czf", + // 4. Tar LanceDB directories (5 min timeout — 5.5GB takes ~100s) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + defer cancel() + if err := exec.CommandContext(ctx, "tar", "czf", filepath.Join(backupDir, "lance-data.tar.gz"), "-C", dataDir, "episodes.lance", "memories.lance", "tombstones.lance", ).Run(); err != nil { + if ctx.Err() == context.DeadlineExceeded { + respondError(w, 500, "lance backup timed out after 5 minutes") + return + } respondError(w, 500, "lance backup failed: "+err.Error()) return } diff --git a/go/internal/api/server.go b/go/internal/api/server.go index 170a2df..07d5bc0 100644 --- a/go/internal/api/server.go +++ b/go/internal/api/server.go @@ -930,7 +930,7 @@ func NewServer() http.Handler { case "merge": _, err = consolPipe.RunMerge() case "prune": - graphStore.Prune(0.15) + graphStore.Prune(0.15) case "decay": // 扫描所有记忆,按衰减率计算 freshness memories, e := ldb.GetCandidatesForForgetting()