Skip to content

Commit 6cf95ca

Browse files
committed
fix: improve server process shutdown with SIGKILL fallback and proper cleanup
1 parent 0ff55d4 commit 6cf95ca

2 files changed

Lines changed: 40 additions & 10 deletions

File tree

lua/opencode/opencode_server.lua

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ local function ensure_vim_leave_autocmd()
2424
callback = function()
2525
local state = require('opencode.state')
2626
if state.opencode_server then
27-
state.opencode_server:shutdown():wait(2000)
27+
pcall(function()
28+
state.opencode_server:shutdown():wait(2000)
29+
end)
2830
end
2931
end,
3032
})
@@ -57,14 +59,20 @@ function OpencodeServer:shutdown()
5759

5860
if self.job and self.job.pid then
5961
pcall(function()
60-
self.job:kill('sigterm')
62+
self.job:kill(vim.loop.constants.SIGTERM)
6163
end)
64+
65+
vim.defer_fn(function()
66+
if self.job and self.job.pid then
67+
pcall(function()
68+
self.job:kill(vim.loop.constants.SIGKILL)
69+
end)
70+
end
71+
end, 1000)
72+
else
73+
self.shutdown_promise:resolve(true)
6274
end
6375

64-
self.job = nil
65-
self.url = nil
66-
self.handle = nil
67-
self.shutdown_promise:resolve(true)
6876
return self.shutdown_promise
6977
end
7078

tests/unit/opencode_server_spec.lua

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,39 @@ describe('opencode.opencode_server', function()
4646

4747
it('shutdown resolves shutdown_promise and clears fields', function()
4848
local server = OpencodeServer.new()
49-
server.job = { pid = 2, kill = function() end }
50-
server.url = 'http://x'
51-
server.handle = 2
49+
local exit_callback
50+
51+
-- Mock vim.system to capture the exit callback
52+
vim.system = function(cmd, opts, on_exit)
53+
exit_callback = on_exit
54+
return { pid = 2, kill = function() end }
55+
end
56+
57+
-- Spawn the server so the exit callback is set up
58+
server:spawn({
59+
cwd = '.',
60+
on_ready = function() end,
61+
on_error = function() end,
62+
on_exit = function() end,
63+
})
64+
5265
local resolved = false
5366
server:get_shutdown_promise():and_then(function()
5467
resolved = true
5568
end)
69+
70+
-- Call shutdown (sends SIGTERM)
5671
server:shutdown()
57-
vim.wait(50, function()
72+
73+
-- Simulate the process exiting by calling the exit callback
74+
vim.schedule(function()
75+
exit_callback({ code = 0, signal = 0 })
76+
end)
77+
78+
vim.wait(100, function()
5879
return resolved
5980
end)
81+
6082
assert.is_true(resolved)
6183
assert.is_nil(server.job)
6284
assert.is_nil(server.url)

0 commit comments

Comments
 (0)