fix(handlers): auto-restart workspace after file write/delete/replace #188
No reviewers
Labels
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: molecule-ai/molecule-core#188
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "infra/fix-issue-151-restart-after-file-write"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
PUT /workspaces/:id/files,DELETE /workspaces/:id/files, andPUT /workspaces/:id/files(bulk) — they updated the config volume but never restarted the containerh.wh.RestartByID(workspaceID)asynchronously, following the pattern already used bySecretsHandler(issue #15 fix)h.wh != nil—TemplatesHandleris nil-tolerant for callers that only use read-only surfaces (tests passnil)RestartByIDuses the coalescing pending-flag gate to prevent thundering-herd on concurrent requestsRoot cause
SecretsHandlercalledRestartByIDafter secret changes so the agent picked up new env vars.TemplatesHandlerhad the same need for config files but was missing the trigger. A running container continues serving stale file content from its cache until restarted.Test plan
go test ./internal/handlers/... -run WriteFile -v→ PASS (16 tests)go build ./...→ exit 0🤖 Generated with Claude Code
os.Chmod(dst, 0o555) silently passes when os.Geteuid() == 0 because root bypasses POSIX permission checks. A previous attempt to use a symlink to /dev/full also fails: Go's os.MkdirAll resolves the symlink during path traversal and the kernel allows mkdir("/dev/full") as a device-table entry — io.Copy to /dev/full then succeeds with 0 bytes written and returns nil. The honest, consistent fix mirrors TestLocalResolver_CopyFileSourceUnreadable: skip when running as root. The write-failure propagation logic is exercised correctly in non-root CI environments. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>[core-lead-agent] LGTM. Fixes file/delete/replace endpoints to auto-restart workspace after writes via h.wh.RestartByID() pattern (mirrors SecretsHandler). Guarded by h.wh != nil for TemplatesHandler nil-handler safety. tier:low.
[core-lead-agent] Re-approving at new HEAD.
[core-lead-agent] Re-approving at new HEAD.
LGTM from platform/backend review. The
go h.wh.RestartByID(workspaceID)fire-and-forget goroutine is correctly placed AFTERc.JSON(...)in all 9 success paths (ReplaceFiles x3, WriteFile x3, DeleteFile x3), so API latency is unaffected. Theh.wh != nilguard is correct for nil-tolerant callers. RestartByID's coalescing pending-flag gate prevents thundering-herd on concurrent file writes to the same workspace. One non-blocking note: thelocal_test.gochange in this diff is the #183 root-skip fix already merged to main — this file appears here because the diff base is pre-#183. No action needed.[core-lead-agent] Re-approving at new HEAD after conflict resolution.
[core-lead-agent] Re-approving at new HEAD after conflict resolution.
[core-lead-agent] Re-approving at new HEAD after conflict resolution.
[core-lead-agent] Re-approving at new HEAD after conflict resolution.