Skip to content

Conversation

@jinzhongjia
Copy link
Contributor

@jinzhongjia jinzhongjia commented Jan 2, 2026

Description:

Problem

The current file lock mechanism for preventing multiple opencode server instances is unstable:

  • Multiple opencode processes can be created due to TOCTOU race conditions
  • Server process not properly cleaned up when neovim exits

Solution

Replace the dual-file lock mechanism with a simpler, more reliable approach:

  • Fixed port binding (default: 41096) as atomic mutex - port binding is an OS-level atomic operation
  • Single lock file - removed .flock file, simplified to single file for client tracking only
  • Blocking shutdown - VimLeavePre now waits for cleanup to complete
  • Graceful error handling - clear error message when port is occupied
  • Cross-platform support - Windows taskkill, Unix SIGTERM/SIGKILL
  • User configurable port - config.server.port

Changes

  • lua/opencode/opencode_server.lua - Remove flock, blocking shutdown, fixed port spawn
  • lua/opencode/server_job.lua - Health check first, port binding as mutex
  • lua/opencode/config.lua - Add server.port config
  • tests/unit/server_job_spec.lua - Update tests

Add a lock file mechanism to coordinate a single server process among
multiple Neovim clients. Track ownership and active clients in
opencode-server.lock to ensure the process persists until the last
instance closes. Additionally, implement URI encoding for API queries.
@jinzhongjia jinzhongjia marked this pull request as ready for review January 2, 2026 11:54
@jinzhongjia
Copy link
Contributor Author

jinzhongjia commented Jan 2, 2026

This PR is generated by AI with opencode and oh my opencode, but I have reviewed this code carefully.

I think this code is ok

Add logic to tests/unit/util_spec.lua to handle year transitions in
date formatting. The assertions now check the year of the timestamp
to determine if the year should be present in the output string.
@jinzhongjia jinzhongjia marked this pull request as draft January 2, 2026 12:11
Replace the `owner` field in the lock file with `server_pid` to
explicitly track the background process. Update `unregister_client`
to return this PID and remove client promotion logic.
nvim returns non-zero exit codes when error messages are printed,
even for expected errors in error handling tests. Changed test runner
to check for actual '[31mFail.*||' patterns in output instead.
@jinzhongjia jinzhongjia force-pushed the feat/single-opencode-client branch from 568d1a6 to f948664 Compare January 2, 2026 12:37
@jinzhongjia jinzhongjia marked this pull request as ready for review January 2, 2026 12:49
@sudo-tee
Copy link
Owner

sudo-tee commented Jan 5, 2026

Thanks for the PR this looks interesting, I will play with it a little bit

@jinzhongjia
Copy link
Contributor Author

If you need to modify code, feel free to contact me!

@jinzhongjia
Copy link
Contributor Author

This repository is great

Copy link
Owner

@sudo-tee sudo-tee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really great feature for the plugin, and it looks stable from the tests I did.

I did add some little nitpicking , but otherwise this looks good

@aweis89
Copy link
Contributor

aweis89 commented Jan 6, 2026

Seems like this will also have the benefit of correctly attaching new sessions to the CWD if that changes within the Neovim instance (e.g. using the :cd .. command)

Move health check logic from OpencodeServer.try_existing_server to a new
static OpencodeApiClient.check_health method using promises.
@jinzhongjia
Copy link
Contributor Author

I have modified the code based on the comment, I think now maybe it is ok?

@jinzhongjia
Copy link
Contributor Author

jinzhongjia commented Jan 6, 2026

Seems like this will also have the benefit of correctly attaching new sessions to the CWD if that changes within the Neovim instance (e.g. using the :cd .. command)

Theoretically yes, but I'm wondering if anyone would actually change the CWD with cd command?
Maybe the system management? But as I know, they all use pure vim or neovim without third plugins

@jinzhongjia
Copy link
Contributor Author

Oh, I found a problem, sometime plugin will create more than one opencode, I will figure out the reason

@jinzhongjia jinzhongjia marked this pull request as draft January 6, 2026 07:46
Replace file lock-based server discovery with direct health checks.
Adds configurable server port and improves shutdown handling with
cross-platform support and graceful process termination.
…ction

Add double-check mechanism to prevent killing server when new clients
register during shutdown, and extract process management utilities.
@jinzhongjia
Copy link
Contributor Author

Shit, I will create a new pr to achieve this

@jinzhongjia jinzhongjia closed this Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants