Skip to content

Bug fixes and performance improvements#1

Merged
cgwalters merged 12 commits intomainfrom
cleanups
Jan 10, 2026
Merged

Bug fixes and performance improvements#1
cgwalters merged 12 commits intomainfrom
cleanups

Conversation

@cgwalters
Copy link
Collaborator

No description provided.

Replace repeated string literals with constants:
- FD_PLACEHOLDER_KEY for "__jsonrpc_fd__"
- FD_INDEX_KEY for "index"
- JSONRPC_VERSION for "2.0"

This also makes collect_placeholder_indices a static method since
it doesn't use self.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Replace `.map_err(|e| Error::Io(e))` with `.map_err(Error::Io)`.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Extract count_fd_placeholders() as a public function and remove the
duplicate implementations from MessageWithFds and Receiver.

This also fixes double JSON parsing in Receiver::try_parse_message -
previously the JSON was parsed once to count placeholders and again
to create the message.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
The demo binary was using tempfile, so move it to examples/demo.rs
where dev-dependencies are available.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Add MAX_FDS_PER_MESSAGE and READ_BUFFER_SIZE constants to clarify
the meaning of the hardcoded values.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
The into_std() call can fail if setting blocking mode fails. Return
a Result instead of panicking.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
The previous implementation converted the tokio UnixStream to a blocking
OwnedFd and used spawn_blocking for sendmsg/recvmsg calls. This had
several issues:

- Moved I/O work off the async runtime to the blocking thread pool
- Did not integrate with tokio's event loop for readiness notifications
- Could exhaust the blocking thread pool under high load

Now use TokioUnixStream::async_io() which properly integrates with
tokio's reactor. The closure returns WouldBlock when the socket isn't
ready, and tokio handles the async waiting. This also simplifies the
code by removing the Mutex wrapper since async_io only requires &self.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
The NDJSON framing is implicit per the JSON-RPC 2.0 transport specification,
so there's no need to call it out explicitly in the crate name.

Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
JSON-RPC doesn't require newline delimiters - JSON is self-delimiting.
Replace NDJSON framing with serde_json's StreamDeserializer to parse
message boundaries directly from the JSON structure.

This makes the protocol a cleaner extension of standard JSON-RPC rather
than imposing an unnecessary framing constraint.

Assisted-by: OpenCode (Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
Add Sender::set_pretty() method to enable human-readable JSON output with
indentation and newlines. This is useful for debugging and interoperability
with tools that expect formatted JSON.

Also add tests verifying the streaming JSON parser correctly handles:
- Pretty-printed JSON with embedded newlines
- Concatenated compact JSON without separators
- Mixed formatting styles

Assisted-by: OpenCode (Sonnet 4)
Add integration tests that verify wire-format compatibility with jsonrpsee
when file descriptors are not present. Tests cover:

- Round-trip message exchange over Unix socket pairs
- Notification handling with proper synchronization
- Error response formatting per JSON-RPC 2.0 spec
- Sequential request handling
- Raw JSON parsing from external sources
- String and null ID handling
- Array params (positional parameters)

Also enable async-client feature for jsonrpsee and add async-trait
dev dependency.

Assisted-by: OpenCode (Sonnet 4)
Simplify socket pair creation by using tokio's UnixStream::pair()
instead of manually creating std sockets, setting non-blocking mode,
and converting to tokio. The tokio method handles all of this internally.
@cgwalters cgwalters merged commit 4e48aff into main Jan 10, 2026
1 check passed
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.

1 participant