forked from molecule-ai/molecule-core
fix(handlers): auto-restart workspace after file write/delete/replace
PUT /workspaces/:id/files and DELETE /workspaces/:id/files updated the config volume but never restarted the container, so the running agent continued serving stale file content from its in-memory cache. The SecretsHandler already had this pattern (issue #15); TemplatesHandler was missing it. Fix: after every successful write/delete in WriteFile, DeleteFile, and ReplaceFiles, call h.wh.RestartByID(workspaceID) asynchronously, guarded by h.wh != nil (nil-tolerant for callers that only use read-only surfaces). The RestartByID coalescing gate prevents thundering-herd on concurrent requests. Fixes #151. Fixes #87 (duplicate effort closed — core-be also filed #183). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
e65633bf15
commit
eaf7dbb7c4
@ -233,6 +233,9 @@ func (h *TemplatesHandler) ReplaceFiles(c *gin.Context) {
|
||||
"files": len(body.Files),
|
||||
"source": "ec2-ssh",
|
||||
})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -264,6 +267,9 @@ func (h *TemplatesHandler) ReplaceFiles(c *gin.Context) {
|
||||
"files": len(body.Files),
|
||||
"source": "container",
|
||||
})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -281,4 +287,7 @@ func (h *TemplatesHandler) ReplaceFiles(c *gin.Context) {
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"status": "replaced", "workspace": workspaceID, "files": len(body.Files), "source": "volume"})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,6 +524,9 @@ func (h *TemplatesHandler) WriteFile(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "saved", "path": filePath})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -535,6 +538,9 @@ func (h *TemplatesHandler) WriteFile(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "saved", "path": filePath})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -546,6 +552,9 @@ func (h *TemplatesHandler) WriteFile(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "saved", "path": filePath})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteFile handles DELETE /workspaces/:id/files/*path
|
||||
@ -592,6 +601,9 @@ func (h *TemplatesHandler) DeleteFile(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "deleted", "path": filePath})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -607,6 +619,9 @@ func (h *TemplatesHandler) DeleteFile(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "deleted", "path": filePath})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -617,5 +632,8 @@ func (h *TemplatesHandler) DeleteFile(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "deleted", "path": filePath})
|
||||
if h.wh != nil {
|
||||
go h.wh.RestartByID(workspaceID)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user