Skip to content

feat(server): share process across multiple instances - #159

Closed
jinzhongjia wants to merge 14 commits into
sudo-tee:mainfrom
jinzhongjia:feat/single-opencode-client
Closed

feat(server): share process across multiple instances#159
jinzhongjia wants to merge 14 commits into
sudo-tee:mainfrom
jinzhongjia:feat/single-opencode-client

Conversation

@jinzhongjia

@jinzhongjia jinzhongjia commented Jan 2, 2026

Copy link
Copy Markdown
Contributor

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

jinzhongjia commented Jan 2, 2026

Copy link
Copy Markdown
Contributor Author

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

sudo-tee commented Jan 5, 2026

Copy link
Copy Markdown
Owner

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

@jinzhongjia

Copy link
Copy Markdown
Contributor Author

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

@jinzhongjia

Copy link
Copy Markdown
Contributor Author

This repository is great

@sudo-tee sudo-tee left a comment

Copy link
Copy Markdown
Owner

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

Comment thread lua/opencode/opencode_server.lua Outdated
Comment thread lua/opencode/opencode_server.lua Outdated
@aweis89

aweis89 commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

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
Copy Markdown
Contributor Author

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

@jinzhongjia

jinzhongjia commented Jan 6, 2026

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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
Copy Markdown
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