Implement WireframeClient with Configurable Runtime#407
Conversation
Introduce a new WireframeClient runtime module that mirrors the server's framing and serialization layers. This includes: - A WireframeClientBuilder with methods to configure serializers, codec settings (max frame length, length prefix format), and socket options (TCP_NODELAY, keepalive, linger, buffer sizes, reuseaddr, reuseport). - ClientCodecConfig for length-delimited codec configuration with clamped max frame length. - SocketOptions struct for TCP socket tuning applied before connecting. - Detailed async runtime methods on WireframeClient for sending, receiving, and request-response call patterns. - ClientError enum covering transport and serialization errors. - Extensive documentation, usage examples, and integration in user guides and design docs. - Behavioral tests with cucumber scenarios, test world, and unit tests validating configuration clamping and socket options. This addition enables flexible, well-typed client connections aligned with server configuration for robust wireframe protocol communication. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Summary by CodeRabbitRelease Notes
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughAdd a Wireframe client runtime with builder, codec and socket configuration, error types, runtime send/receive/call APIs, unit and integration tests including Cucumber scenarios, and add the Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Dev as User/Caller
participant Builder as WireframeClientBuilder
participant Socket as TcpSocket (socket2/Tokio)
participant Codec as LengthDelimitedCodec
participant Framed as Framed<TcpStream, Codec>
participant Client as WireframeClient
participant Serializer as Serializer (e.g. Bincode)
Dev->>Builder: new() / configure(serializer, codec_config, socket_options)
Dev->>Builder: connect(addr: SocketAddr)
activate Builder
Builder->>Socket: create (v4/v6) & apply SocketOptions
Builder->>Socket: connect(addr)
Socket-->>Builder: connected TcpStream
Builder->>Codec: build with max_frame_length, length_format, endianness
Builder->>Framed: wrap TcpStream with Codec
Builder->>Client: construct WireframeClient with Framed + Serializer
deactivate Builder
Dev->>Client: send(&message)
activate Client
Client->>Serializer: encode(&message)
Serializer->>Framed: write framed bytes
Framed->>Server: transmit frame
deactivate Client
Dev->>Client: receive()
activate Client
Framed->>Client: read frame
Client->>Serializer: decode frame
Serializer-->>Dev: return Message
deactivate Client
Dev->>Client: call(&req)
activate Client
Client->>Client: send(&req)
Client->>Client: receive() -> response
Client-->>Dev: Result<Response> / ClientError
deactivate Client
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (6)
🧰 Additional context used📓 Path-based instructions (4)**/*.rs📄 CodeRabbit inference engine (AGENTS.md)
Files:
⚙️ CodeRabbit configuration file
Files:
docs/**/*.md📄 CodeRabbit inference engine (docs/contents.md)
Files:
docs/**/*.{rs,md}📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)
Files:
**/*.md📄 CodeRabbit inference engine (AGENTS.md)
Files:
⚙️ CodeRabbit configuration file
Files:
🧬 Code graph analysis (3)tests/worlds/client_runtime.rs (3)
src/client/config.rs (1)
src/client/mod.rs (2)
🔍 Remote MCPNow let me search for more specific information about error handling patterns and codec best practices in Rust:Based on my search results, I have gathered sufficient context to provide a comprehensive summary of relevant information for reviewing this pull request. Summary of Relevant Context for PR #407 ReviewSocket Options Configuration & TCP SettingsTcpSocket wraps an operating system socket and enables the caller to configure the socket before establishing a TCP connection or accepting inbound connections, with the ability to set socket options and explicitly bind the socket with a socket address. The PR's
Length-Delimited Codec ConfigurationThe PR's
Error Handling with Boxed ErrorsThe PR uses
Async Error Handling Patterns
Builder Pattern for ConfigurationThe
[::web_search::] provides TCP socket configuration best practices and codec documentation context. 🔇 Additional comments (29)
Comment |
Reviewer's GuideIntroduce a configurable Wireframe client runtime that mirrors the server’s framing/serialization, including a builder with codec and socket options, a dedicated client error type, request/response operations, docs, and end-to-end tests (unit, integration, and cucumber). Sequence diagram for WireframeClient connect and call flowsequenceDiagram
actor Developer
participant WireframeClientBuilder
participant ClientCodecConfig
participant SocketOptions
participant TcpSocket
participant LengthDelimitedCodec
participant WireframeClient
participant Serializer
participant Server
Developer->>WireframeClientBuilder: builder()
Developer->>WireframeClientBuilder: serializer(BincodeSerializer)
Developer->>WireframeClientBuilder: codec_config(ClientCodecConfig)
Developer->>WireframeClientBuilder: socket_options(SocketOptions)
Developer->>WireframeClientBuilder: connect(addr)
WireframeClientBuilder->>TcpSocket: new_v4 or new_v6()
WireframeClientBuilder->>SocketOptions: apply(TcpSocket)
SocketOptions-->>WireframeClientBuilder: configured socket
WireframeClientBuilder->>TcpSocket: connect(addr)
TcpSocket-->>WireframeClientBuilder: TcpStream
WireframeClientBuilder->>ClientCodecConfig: build_codec()
ClientCodecConfig-->>WireframeClientBuilder: LengthDelimitedCodec
WireframeClientBuilder->>LengthDelimitedCodec: wrap TcpStream as Framed
LengthDelimitedCodec-->>WireframeClientBuilder: Framed
WireframeClientBuilder-->>Developer: WireframeClient
Developer->>WireframeClient: call(request)
WireframeClient->>WireframeClient: send(request)
WireframeClient->>Serializer: serialize(request)
Serializer-->>WireframeClient: bytes
WireframeClient->>LengthDelimitedCodec: send(bytes)
LengthDelimitedCodec->>Server: TCP frame
Server-->>LengthDelimitedCodec: response frame
LengthDelimitedCodec-->>WireframeClient: bytes
WireframeClient->>Serializer: deserialize(bytes)
Serializer-->>WireframeClient: response
WireframeClient-->>Developer: response
Updated class diagram for Wireframe client runtime typesclassDiagram
class WireframeClient {
- Framed framed
- Serializer serializer
- ClientCodecConfig codec_config
+ send(message) Result
+ receive() Result
+ call(request) Result
+ codec_config() ClientCodecConfig
+ builder() WireframeClientBuilder
}
class WireframeClientBuilder {
- Serializer serializer
- ClientCodecConfig codec_config
- SocketOptions socket_options
+ new() WireframeClientBuilder
+ serializer(serializer) WireframeClientBuilder
+ codec_config(codec_config) WireframeClientBuilder
+ max_frame_length(max_frame_length) WireframeClientBuilder
+ length_format(length_format) WireframeClientBuilder
+ socket_options(socket_options) WireframeClientBuilder
+ nodelay(enabled) WireframeClientBuilder
+ keepalive(enabled) WireframeClientBuilder
+ linger(duration) WireframeClientBuilder
+ send_buffer_size(size) WireframeClientBuilder
+ recv_buffer_size(size) WireframeClientBuilder
+ reuseaddr(enabled) WireframeClientBuilder
+ connect(addr) Result
}
class ClientCodecConfig {
- LengthFormat length_format
- usize max_frame_length
+ max_frame_length(max_frame_length) ClientCodecConfig
+ length_format(length_format) ClientCodecConfig
+ max_frame_length_value() usize
+ length_format_value() LengthFormat
+ build_codec() LengthDelimitedCodec
}
class SocketOptions {
- Option~bool~ nodelay
- Option~bool~ keepalive
- Option~LingerSetting~ linger
- Option~u32~ send_buffer_size
- Option~u32~ recv_buffer_size
- Option~bool~ reuseaddr
- Option~bool~ reuseport
+ nodelay(enabled) SocketOptions
+ keepalive(enabled) SocketOptions
+ linger(duration) SocketOptions
+ send_buffer_size(size) SocketOptions
+ recv_buffer_size(size) SocketOptions
+ reuseaddr(enabled) SocketOptions
+ reuseport(enabled) SocketOptions
+ apply(socket) Result
}
class LingerSetting {
<<enum>>
Disabled
Duration
+ to_option() Option
}
class ClientError {
<<enum>>
Io
Serialize
Deserialize
Disconnected
}
class Serializer {
<<trait>>
+ serialize(message) Result
+ deserialize(bytes) Result
}
class BincodeSerializer {
}
class LengthFormat {
}
class LengthDelimitedCodec {
}
class TcpSocket {
}
class TcpStream {
}
WireframeClientBuilder --> WireframeClient : builds
WireframeClient --> ClientCodecConfig : uses
WireframeClient --> Serializer : uses
WireframeClient --> LengthDelimitedCodec : framed_io
WireframeClientBuilder --> ClientCodecConfig : configures
WireframeClientBuilder --> SocketOptions : configures
SocketOptions --> TcpSocket : applies
TcpSocket --> TcpStream : connects
ClientCodecConfig --> LengthDelimitedCodec : builds
BincodeSerializer ..|> Serializer
WireframeClient --> ClientError : returns
WireframeClientBuilder --> ClientError : returns
ClientError --> Io
ClientError --> Serialize
ClientError --> Deserialize
ClientError --> Disconnected
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ent builder - Updated SocketOptions to allow keepalive duration configuration instead of boolean. - WireframeClientBuilder.keepalive now accepts Option<Duration> to configure keepalive. - Applied keepalive setting to TCP stream socket options. - Added unit and integration tests for socket options including keepalive. - Added client runtime feature test for error reporting on oversized frames. - Updated usage docs and examples to demonstrate keepalive duration usage. - Introduced new method to access underlying TcpStream from WireframeClient. This enables TCP keepalive tuning for clients, improving connection reliability. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix: Comment on lines +212 to +228 async fn builder_applies_reuseport_option() {
let (addr, accept) = spawn_listener().await;
let client = WireframeClient::builder()
.reuseport(true)
.connect(addr)
.await
.expect("connect client");
let sock_ref = SockRef::from(client.tcp_stream());
assert!(
sock_ref.reuse_port().expect("query SO_REUSEPORT"),
"SO_REUSEPORT should be enabled when configured via builder"
);
let _server_stream = accept.await.expect("join accept task");
}❌ New issue: Code Duplication |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Corrected misplaced or inconsistent doc comment lines in src/client/builder.rs and src/client/config.rs to improve example code readability and maintain proper Rust doc comment style. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
This adds an integration test in `tests/client_runtime.rs` to verify that the wireframe client correctly surfaces errors when sending frames that exceed the server's maximum frame length. It ensures the client receives the appropriate transport or disconnection error upon server rejection of oversized frames. Additionally, client socket option tests in `src/client/tests.rs` were refactored to use a shared helper function for cleaner and more concise test code. Minor error handling improvements wrapping serializer errors with Box were also applied in `src/client/runtime.rs`. Small documentation wording clarifications were made in `docs/users-guide.md`. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
…wlines Refactored the client_runtime.rs test to consolidate method calls onto single lines, improving readability without changing behavior. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 809 🏁 Script executed: Length of output: 84 🏁 Script executed: Length of output: 759 🏁 Script executed: Length of output: 179 🏁 Script executed: Length of output: 1937 🏁 Script executed: Length of output: 642 🏁 Script executed: Length of output: 6349 @leynos: Excellent news! All 9 comments have now been fully resolved. Here's the comprehensive status: ✅ All Comments ResolvedPreviously Unresolved - Now Fixed:Comment 1 (Error wrapping in
Comment 5 (Oversized frame error test): ✅ RESOLVED
Comment 9 (Second-person pronouns in documentation): ✅ RESOLVED
Previously Resolved:Comment 2 ✅ Conservative read buffer allocation implemented All feedback from the code review has been successfully addressed! 🎉 |
- Added `socket2` dependency to enable detailed TCP keepalive configuration. - Updated SocketOptions to use `socket2::TcpKeepalive` for keepalive duration setting. - Support explicit enable/disable of TCP keepalive with duration control. - Cleaned up error wrapping in client runtime serialization/deserialization. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/cucumber.rs (1)
1-24: Update module documentation to include ClientRuntimeWorld.The module doc comment lists five test suites (lines 4-9) but omits the newly added
ClientRuntimeWorld. Add an entry describing the client runtime test suite to maintain documentation accuracy.🔎 Proposed fix
//! Cucumber test runner for integration tests. //! -//! Orchestrates five distinct test suites: +//! Orchestrates six distinct test suites: //! - `PanicWorld`: Tests server resilience during connection panics //! - `CorrelationWorld`: Tests correlation ID propagation in multi-frame responses //! - `StreamEndWorld`: Verifies end-of-stream signalling //! - `MultiPacketWorld`: Tests channel-backed multi-packet response delivery //! - `FragmentWorld`: Tests fragment metadata enforcement and reassembly primitives +//! - `ClientRuntimeWorld`: Tests client runtime configuration and framing behaviour //! //! # Example //! //! The runner executes feature files sequentially: //! ```text //! tests/features/connection_panic.feature -> PanicWorld context //! tests/features/correlation_id.feature -> CorrelationWorld context //! tests/features/stream_end.feature -> StreamEndWorld context //! tests/features/multi_packet.feature -> MultiPacketWorld context //! tests/features/fragment.feature -> FragmentWorld context +//! tests/features/client_runtime.feature -> ClientRuntimeWorld context //! ```
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
Cargo.toml(1 hunks)docs/roadmap.md(1 hunks)docs/users-guide.md(3 hunks)docs/wireframe-client-design.md(4 hunks)src/client/builder.rs(1 hunks)src/client/config.rs(1 hunks)src/client/error.rs(1 hunks)src/client/mod.rs(1 hunks)src/client/runtime.rs(1 hunks)src/client/tests.rs(1 hunks)src/lib.rs(2 hunks)tests/client_runtime.rs(1 hunks)tests/cucumber.rs(2 hunks)tests/features/client_runtime.feature(1 hunks)tests/steps/client_steps.rs(1 hunks)tests/steps/mod.rs(1 hunks)tests/world.rs(1 hunks)tests/worlds/client_runtime.rs(1 hunks)tests/worlds/mod.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
docs/**/*.md
📄 CodeRabbit inference engine (docs/contents.md)
Follow the documentation style guide conventions when writing project documentation
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffix in words like 'realize' and 'organization', -lyse suffix in words like 'analyse', -our suffix in words like 'colour', -re suffix in words like 'centre', double 'l' in words like 'cancelled', maintain 'e' in words like 'likeable', -ogue suffix in words like 'catalogue'
The word 'outwith' is acceptable in British English documentation
Keep US spelling when used in an API (for example, 'color')
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns: 'Lille Industries are expanding'
Write headings in sentence case in documentation
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for Markdown files
Always provide a language identifier for fenced code blocks in documentation; use 'plaintext' for non-code text
Use '-' as the first level bullet and renumber lists when items change in documentation
Prefer inline links using 'text' or angle brackets around the URL in documentation
Ensure blank lines before and after bulleted lists and fenced blocks in documentation
Ensure tables have a delimiter line below the header row in documentation
Expand any uncommon acronym on first use in documentation (for example, Continuous Integration (CI))
Wrap paragraphs at 80 columns in documentation
Wrap code at 120 columns in documentation
Do not wrap tables in documentation
Use footnotes referenced with '[^label]' in documentation
Include Mermaid diagrams where they add clarity to documentation
When embedding figures in documentation, use '' and provide brief alt text describing the content
Add a short description before each Mermaid diagram so screen readers can understand itWrite official documentation with se...
Files:
docs/roadmap.mddocs/users-guide.mddocs/wireframe-client-design.md
docs/**/*.{rs,md}
📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)
Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency
Files:
docs/roadmap.mddocs/users-guide.mddocs/wireframe-client-design.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
**/*.md: Validate Markdown files usingmake markdownlint.
Runmake fmtafter any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by runningmake nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.
Files:
docs/roadmap.mddocs/users-guide.mddocs/wireframe-client-design.md
⚙️ CodeRabbit configuration file
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Headings must not be wrapped.
- Documents must start with a level 1 heading
- Headings must correctly increase or decrease by no more than one level at a time
- Use GitHub-flavoured Markdown style for footnotes and endnotes.
- Numbered footnotes must be numbered by order of appearance in the document.
Files:
docs/roadmap.mddocs/users-guide.mddocs/wireframe-client-design.md
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: Runmake check-fmt(cargo fmt --workspace -- --check) before committing to validate Rust formatting across the entire workspace without modifying files.
Runmake lint(cargo clippy --workspace --all-targets --all-features -- -D warnings) before committing to lint every target with all features enabled and deny all Clippy warnings.
Runmake test(cargo test --workspace) before committing to run the full workspace test suite.
Clippy warnings MUST be disallowed. Fix any warnings emitted during tests in the code itself rather than silencing them.
Usemake fmt(cargo fmt --workspace) to apply formatting fixes reported by the formatter check.
Where a Rust function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a Rust function has too many parameters, group related parameters in meaningfully named structs.
Where a Rust function is returning a large error, consider usingArcto reduce the amount of data returned.
Write unit and behavioural tests for new Rust functionality. Run both before and after making any change.
Every Rust module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public Rust APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessarymutbindings in Rust code.
Avoidunsafecode in Rust unless absolutely necessary, and document any usage clearly with a 'SAFETY' comment.
Place function attributes after doc comments in Rust code.
Do not usereturnin single-line Rust functions.
Use predicate functions for Rust conditional criteria with more than two branches.
Lints must not be silenced in Rust except as a last resort. Lint rule suppressions must be tightly scoped and include a clear reason.
Useconcat!()to combine long string literals in Rust rather than escaping newlines with a backslash.
Prefer single-line versions of Rust functions where...
Files:
tests/worlds/mod.rstests/world.rssrc/lib.rssrc/client/tests.rssrc/client/error.rssrc/client/mod.rstests/steps/mod.rstests/client_runtime.rstests/steps/client_steps.rstests/cucumber.rssrc/client/runtime.rstests/worlds/client_runtime.rssrc/client/builder.rssrc/client/config.rs
⚙️ CodeRabbit configuration file
**/*.rs: * Seek to keep the cognitive complexity of functions no more than 9.
- Adhere to single responsibility and CQRS
- Place function attributes after doc comments.
- Do not use
returnin single-line functions.- Move conditionals with >2 branches into a predicate function.
- Avoid
unsafeunless absolutely necessary.- Every module must begin with a
//!doc comment that explains the module's purpose and utility.- Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Lints must not be silenced except as a last resort.
#[allow]is forbidden.- Only narrowly scoped
#[expect(lint, reason = "...")]is allowed.- No lint groups, no blanket or file-wide suppression.
- Include
FIXME:with link if a fix is expected.- Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.
- Use
rstestfixtures for shared setup and to avoid repetition between tests.- Replace duplicated tests with
#[rstest(...)]parameterised cases.- Prefer
mockallfor mocks/stubs.- Prefer
.expect()over.unwrap()in tests..expect()and.unwrap()are forbidden outside of tests. Errors must be propagated.- Ensure that any API or behavioural changes are reflected in the documentation in
docs/- Ensure that any completed roadmap steps are recorded in the appropriate roadmap in
docs/- Files must not exceed 400 lines in length
- Large modules must be decomposed
- Long match statements or dispatch tables should be decomposed by domain and collocated with targets
- Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
- Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such
- For testing of functionality depending upon environment variables, dependency injection and...
Files:
tests/worlds/mod.rstests/world.rssrc/lib.rssrc/client/tests.rssrc/client/error.rssrc/client/mod.rstests/steps/mod.rstests/client_runtime.rstests/steps/client_steps.rstests/cucumber.rssrc/client/runtime.rstests/worlds/client_runtime.rssrc/client/builder.rssrc/client/config.rs
Cargo.toml
📄 CodeRabbit inference engine (AGENTS.md)
Cargo.toml: Use explicit version ranges inCargo.tomland keep dependencies up-to-date.
All crate versions specified inCargo.tomlmust use SemVer-compatible caret requirements (e.g.,some-crate = "1.2.3"). Wildcard (*) or open-ended inequality (>=) version requirements are strictly forbidden. Tilde requirements (~) should only be used where a dependency must be locked to patch-level updates for a specific, documented reason.
Files:
Cargo.toml
🧬 Code graph analysis (7)
src/client/tests.rs (4)
src/frame/format.rs (3)
bytes(54-54)endianness(58-58)u32_be(70-70)src/client/runtime.rs (1)
builder(64-64)src/client/config.rs (3)
default(32-37)max_frame_length_value(90-90)length_format_value(104-104)src/client/builder.rs (2)
default(52-52)new(42-48)
src/client/mod.rs (1)
src/client/runtime.rs (1)
builder(64-64)
tests/client_runtime.rs (1)
src/client/runtime.rs (1)
builder(64-64)
tests/steps/client_steps.rs (2)
src/client/config.rs (1)
max_frame_length(54-57)src/client/builder.rs (1)
max_frame_length(109-112)
src/client/runtime.rs (1)
src/client/builder.rs (3)
serializer(70-79)new(42-48)codec_config(93-96)
tests/worlds/client_runtime.rs (3)
src/client/config.rs (2)
max_frame_length(54-57)default(32-37)src/client/builder.rs (4)
max_frame_length(109-112)new(42-48)codec_config(93-96)default(52-52)src/client/runtime.rs (2)
builder(64-64)codec_config(200-200)
src/client/builder.rs (2)
src/client/config.rs (10)
default(32-37)max_frame_length(54-57)length_format(74-77)nodelay(190-193)keepalive(209-215)linger(231-237)send_buffer_size(251-254)recv_buffer_size(268-271)reuseaddr(285-288)reuseport(308-311)src/client/runtime.rs (1)
codec_config(200-200)
🪛 GitHub Actions: CI
src/client/runtime.rs
[error] 98-98: Clippy: redundant closure found. Remove the unnecessary closure at src/client/runtime.rs:98:22.
🪛 GitHub Check: build-test
src/client/runtime.rs
[failure] 135-135:
redundant closure
[failure] 98-98:
redundant closure
🪛 LanguageTool
docs/roadmap.md
[uncategorized] ~295-~295: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...lement WireframeClient and its builder so callers can configure serializers, ...
(COMMA_COMPOUND_SENTENCE_2)
🔍 Remote MCP
Let me try a web search to find relevant technical information about the socket2 crate and best practices for TCP socket configuration that would be applicable to this PR review.## Summary of Relevant Context for Pull Request Review
Based on my research into the technologies and patterns used in this PR, here is the relevant context for reviewing the WireframeClient implementation:
Socket Configuration via socket2
The socket2 crate mirrors raw socket semantics closely, with almost all methods corresponding precisely to one libc or OS API call. The PR uses socket2 to configure TCP socket options, particularly TCP keepalive. On Unix, setting TCP keepalive sets both SO_KEEPALIVE and TCP_KEEPALIVE/TCP_KEEPIDLE options (depending on platform), while on Windows it sets the SIO_KEEPALIVE_VALS option.
Important caveat: On Windows, unconfigured keepalive parameters may be overwritten with defaults, so the function should either be called once per socket or with identical parameters each time.
TCP Socket Configuration in tokio
TcpSocket should only be used directly when the default configuration doesn't meet requirements, and such sockets are typically used together with socket2 to configure socket options not available on TcpSocket.
Length-Delimited Framing
Length-delimited framing prefixes frame data with a frame head specifying frame length, providing utilities that allow consumers to work with entire frames without manual buffering or framing logic. The default format uses a big-endian u32 header with the frame payload.
Key Review Points
Socket Options: The PR's socket option configuration aligns with standard practice, using socket2 for cross-platform TCP keepalive and other low-level options before connection.
Builder Pattern: The fluent builder design allows composition of socket options before connection, which is a common pattern in async Rust for pre-connection configuration.
Frame Length Constraints: LengthDelimitedCodec enforces maximum frame sizes, rejecting frames larger than configured limits, supporting the PR's max_frame_length clamping and validation.
[::web_search::]
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (29)
Cargo.toml (1)
47-47: LGTM!The socket2 dependency addition is appropriate for the client runtime socket configuration features and follows the implicit caret versioning guideline.
src/client/tests.rs (3)
1-46: LGTM!The module documentation is clear, and the helper functions effectively reduce test duplication as requested in previous reviews. The
assert_builder_optionhelper provides a clean abstraction for testing socket configuration.
48-105: LGTM!The codec configuration tests comprehensively address the previous review feedback. The
build_codec_configures_length_delimited_codectest properly verifies that the configured length field format and endianness are applied to the codec through encode/decode round-tripping and wire-format inspection.
107-218: LGTM!The socket option tests comprehensively cover all builder configuration options as requested in previous reviews. The use of the shared helper function eliminates duplication, and platform-specific guards for
SO_REUSEPORTare correctly applied.tests/worlds/mod.rs (1)
29-29: LGTM!The module declaration properly exposes the client runtime world for use in cucumber tests.
tests/world.rs (1)
8-8: LGTM!The re-export follows the established pattern for exposing test worlds.
tests/steps/mod.rs (1)
6-6: LGTM!The module declaration properly wires the client step definitions into the cucumber test framework.
tests/cucumber.rs (1)
29-46: LGTM!The ClientRuntimeWorld is properly imported and integrated into the cucumber test runner.
src/lib.rs (2)
12-12: LGTM!The client module is properly exposed as part of the public API.
34-34: LGTM!The client type re-exports follow the established pattern and provide a clean public API surface for the client runtime.
tests/features/client_runtime.feature (1)
1-12: Well-structured BDD scenarios covering both happy and error paths.The feature file provides good coverage for the client runtime: the first scenario validates normal echo behaviour within frame limits, whilst the second scenario exercises the error path when frames exceed the server's configured maximum. This aligns well with the PR objectives.
src/client/error.rs (1)
1-20: LGTM!The error enum is well-structured with appropriate variants for transport, serialization, and connection states. Using
Box<dyn Error + Send + Sync>for serialization errors provides flexibility across different serializer implementations, and the#[source]attribute ensures proper error chaining.tests/client_runtime.rs (1)
13-55: Good integration test covering oversized frame behaviour.The test correctly validates that the client surfaces an appropriate error when sending frames that exceed the server's configured maximum. The assertion covering both
DisconnectedandIovariants is sensible since the exact error depends on timing and transport behaviour.docs/wireframe-client-design.md (1)
1-118: Design document accurately reflects the implemented API.The updates correctly document the API changes:
SocketAddrparameter forconnect, borrowed request incall(&request), andmax_frame_lengthbuilder method. The implementation decisions section provides useful context on clamping and defaults.src/client/mod.rs (1)
1-17: LGTM!The module structure is clean and follows Rust conventions. The re-exports provide a well-organised public API surface that aligns with the crate's top-level exports.
tests/steps/client_steps.rs (1)
1-35: LGTM!The step definitions are appropriately thin, delegating to the world's methods for test logic. This keeps the step definitions focused on mapping Gherkin syntax to test actions whilst maintaining good separation of concerns.
src/client/runtime.rs (2)
32-44: Good use offinish_non_exhaustive()in Debug implementation.This correctly signals that the struct has additional fields not shown in the debug output, which is appropriate for omitting the framed stream and serializer.
173-179: Clean composition ofsendandreceive.The
callmethod elegantly composes the two lower-level operations, providing a convenient request-response pattern for callers.tests/worlds/client_runtime.rs (4)
35-57: LGTM!The echo server setup correctly binds to an ephemeral port, spawns an async task with appropriate early-return handling, and stores the address and handle for later verification.
64-72: LGTM!The client connection correctly retrieves the server address, configures the codec, and establishes the connection via the builder pattern with proper error propagation.
79-106: LGTM!Both payload methods correctly implement the test scenarios—
send_payloadfor successful echo andsend_payload_expect_errorfor the oversized frame rejection case mentioned in the PR objectives.
112-144: LGTM!The verification methods correctly validate echoed payloads and error variants, with proper server task cleanup. The duplicated cleanup logic is acceptable given the test context and clarity benefits.
src/client/config.rs (4)
11-120: LGTM!
ClientCodecConfigcorrectly implements frame length clamping between 64 bytes and 16 MiB, andbuild_codec()properly configures theLengthDelimitedCodecwith the specified endianness and length field format.
139-175: LGTM!The
SocketOptionsstruct correctly uses platform-conditional compilation forreuseport, and the internalLingerSetting/KeepAliveSettingenums appropriately model the tri-state configuration (unset/disabled/duration).
177-311: LGTM!The
SocketOptionsbuilder methods are consistent, properly annotated with#[must_use], and include appropriate platform guards forreuseport.
313-352: LGTM!The
apply()method correctly configures all socket options, including the two-step TCP keepalive setup viasocket2::SockRefandTcpKeepalivethat addresses the earlier API mismatch concern.src/client/builder.rs (3)
24-53: LGTM!The builder struct correctly uses a default type parameter for the serializer, and the
Defaultimplementation properly delegates tonew().
55-267: LGTM!The builder methods correctly delegate to the underlying
ClientCodecConfigandSocketOptionstypes, and the generic type transformation inserializer()is properly implemented.
288-309: LGTM!The
connect()method correctly handles IPv4/IPv6 socket creation, applies socket options before connection, and uses a conservative initial buffer allocation (capped at 64 KiB) as per the resolved performance concern. The doc example appropriately uses.expect().
…clarity Refactored the SocketOptions struct's apply method to delegate to individual methods for each socket option (e.g., nodelay, keepalive, linger) improving readability and maintenance. Added corresponding unit tests to verify socket option behaviors. Also improved error handling simplification and minor related test updates. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (2)
docs/roadmap.md (1)
290-297: Add comma before coordinating conjunction.Insert a comma before "so" on line 295 when it connects two independent clauses.
🔎 Proposed fix
- - [x] Implement `WireframeClient` and its builder so callers can configure + - [x] Implement `WireframeClient` and its builder, so callers can configure serializers, codec settings (including `max_frame_length` parity), and socket options before connecting.docs/users-guide.md (1)
390-425: Addno_runattribute to the code example.This code example connects to
127.0.0.1:7878, which will fail at doc-test time since no server is running. Mark the code block withno_runto prevent doc-test failures whilst preserving syntax validation.🔎 Proposed fix
-```rust +```rust,no_run use std::{net::SocketAddr, time::Duration};
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (8)
docs/roadmap.mddocs/users-guide.mdsrc/client/config.rssrc/client/runtime.rssrc/client/tests.rstests/connection.rstests/cucumber.rstests/worlds/client_runtime.rs
🧰 Additional context used
📓 Path-based instructions (4)
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: Runmake check-fmt(cargo fmt --workspace -- --check) before committing to validate Rust formatting across the entire workspace without modifying files.
Runmake lint(cargo clippy --workspace --all-targets --all-features -- -D warnings) before committing to lint every target with all features enabled and deny all Clippy warnings.
Runmake test(cargo test --workspace) before committing to run the full workspace test suite.
Clippy warnings MUST be disallowed. Fix any warnings emitted during tests in the code itself rather than silencing them.
Usemake fmt(cargo fmt --workspace) to apply formatting fixes reported by the formatter check.
Where a Rust function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a Rust function has too many parameters, group related parameters in meaningfully named structs.
Where a Rust function is returning a large error, consider usingArcto reduce the amount of data returned.
Write unit and behavioural tests for new Rust functionality. Run both before and after making any change.
Every Rust module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public Rust APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessarymutbindings in Rust code.
Avoidunsafecode in Rust unless absolutely necessary, and document any usage clearly with a 'SAFETY' comment.
Place function attributes after doc comments in Rust code.
Do not usereturnin single-line Rust functions.
Use predicate functions for Rust conditional criteria with more than two branches.
Lints must not be silenced in Rust except as a last resort. Lint rule suppressions must be tightly scoped and include a clear reason.
Useconcat!()to combine long string literals in Rust rather than escaping newlines with a backslash.
Prefer single-line versions of Rust functions where...
Files:
tests/connection.rstests/cucumber.rssrc/client/tests.rssrc/client/runtime.rstests/worlds/client_runtime.rssrc/client/config.rs
⚙️ CodeRabbit configuration file
**/*.rs: * Seek to keep the cognitive complexity of functions no more than 9.
- Adhere to single responsibility and CQRS
- Place function attributes after doc comments.
- Do not use
returnin single-line functions.- Move conditionals with >2 branches into a predicate function.
- Avoid
unsafeunless absolutely necessary.- Every module must begin with a
//!doc comment that explains the module's purpose and utility.- Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Lints must not be silenced except as a last resort.
#[allow]is forbidden.- Only narrowly scoped
#[expect(lint, reason = "...")]is allowed.- No lint groups, no blanket or file-wide suppression.
- Include
FIXME:with link if a fix is expected.- Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.
- Use
rstestfixtures for shared setup and to avoid repetition between tests.- Replace duplicated tests with
#[rstest(...)]parameterised cases.- Prefer
mockallfor mocks/stubs.- Prefer
.expect()over.unwrap()in tests..expect()and.unwrap()are forbidden outside of tests. Errors must be propagated.- Ensure that any API or behavioural changes are reflected in the documentation in
docs/- Ensure that any completed roadmap steps are recorded in the appropriate roadmap in
docs/- Files must not exceed 400 lines in length
- Large modules must be decomposed
- Long match statements or dispatch tables should be decomposed by domain and collocated with targets
- Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
- Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such
- For testing of functionality depending upon environment variables, dependency injection and...
Files:
tests/connection.rstests/cucumber.rssrc/client/tests.rssrc/client/runtime.rstests/worlds/client_runtime.rssrc/client/config.rs
docs/**/*.md
📄 CodeRabbit inference engine (docs/contents.md)
Follow the documentation style guide conventions when writing project documentation
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffix in words like 'realize' and 'organization', -lyse suffix in words like 'analyse', -our suffix in words like 'colour', -re suffix in words like 'centre', double 'l' in words like 'cancelled', maintain 'e' in words like 'likeable', -ogue suffix in words like 'catalogue'
The word 'outwith' is acceptable in British English documentation
Keep US spelling when used in an API (for example, 'color')
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns: 'Lille Industries are expanding'
Write headings in sentence case in documentation
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for Markdown files
Always provide a language identifier for fenced code blocks in documentation; use 'plaintext' for non-code text
Use '-' as the first level bullet and renumber lists when items change in documentation
Prefer inline links using 'text' or angle brackets around the URL in documentation
Ensure blank lines before and after bulleted lists and fenced blocks in documentation
Ensure tables have a delimiter line below the header row in documentation
Expand any uncommon acronym on first use in documentation (for example, Continuous Integration (CI))
Wrap paragraphs at 80 columns in documentation
Wrap code at 120 columns in documentation
Do not wrap tables in documentation
Use footnotes referenced with '[^label]' in documentation
Include Mermaid diagrams where they add clarity to documentation
When embedding figures in documentation, use '' and provide brief alt text describing the content
Add a short description before each Mermaid diagram so screen readers can understand itWrite official documentation with se...
Files:
docs/users-guide.mddocs/roadmap.md
docs/**/*.{rs,md}
📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)
Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency
Files:
docs/users-guide.mddocs/roadmap.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
**/*.md: Validate Markdown files usingmake markdownlint.
Runmake fmtafter any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by runningmake nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.
Files:
docs/users-guide.mddocs/roadmap.md
⚙️ CodeRabbit configuration file
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Headings must not be wrapped.
- Documents must start with a level 1 heading
- Headings must correctly increase or decrease by no more than one level at a time
- Use GitHub-flavoured Markdown style for footnotes and endnotes.
- Numbered footnotes must be numbered by order of appearance in the document.
Files:
docs/users-guide.mddocs/roadmap.md
🧬 Code graph analysis (5)
tests/connection.rs (2)
src/app/frame_handling.rs (1)
record(31-47)wireframe_testing/src/logging.rs (1)
logger(82-82)
src/client/tests.rs (3)
src/frame/format.rs (3)
bytes(54-54)endianness(58-58)u32_be(70-70)src/client/config.rs (7)
default(32-37)max_frame_length_value(90-90)length_format_value(104-104)keepalive(209-215)linger(231-237)send_buffer_size(251-254)recv_buffer_size(268-271)src/client/builder.rs (6)
default(52-52)new(42-48)keepalive(176-179)linger(194-197)send_buffer_size(210-213)recv_buffer_size(226-229)
src/client/runtime.rs (1)
src/client/builder.rs (3)
serializer(70-79)new(42-48)codec_config(93-96)
tests/worlds/client_runtime.rs (3)
src/client/config.rs (2)
max_frame_length(54-57)default(32-37)src/client/builder.rs (4)
max_frame_length(109-112)new(42-48)codec_config(93-96)default(52-52)src/client/runtime.rs (2)
builder(64-64)codec_config(200-200)
src/client/config.rs (2)
src/client/builder.rs (11)
default(52-52)max_frame_length(109-112)length_format(125-128)nodelay(158-161)keepalive(176-179)linger(194-197)send_buffer_size(210-213)recv_buffer_size(226-229)reuseaddr(242-245)reuseport(264-267)new(42-48)src/client/runtime.rs (1)
builder(64-64)
🪛 LanguageTool
docs/roadmap.md
[uncategorized] ~290-~290: Do not mix variants of the same word (‘serialisation’ and ‘serialization’) within a single text.
Context: ...time that mirrors the server's framing, serialisation, and lifecycle layers, so both sides sh...
(EN_WORD_COHERENCY)
[uncategorized] ~295-~295: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...lement WireframeClient and its builder so callers can configure serializers, ...
(COMMA_COMPOUND_SENTENCE_2)
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Sourcery review
- GitHub Check: build-test
🔇 Additional comments (26)
tests/cucumber.rs (2)
1-38: LGTM!Module documentation correctly updated to reflect six test suites, and the import structure is clean.
40-48: LGTM!The new
ClientRuntimeWorldtest suite is correctly wired into the sequential test runner.tests/connection.rs (1)
209-238: LGTM!The addition of correlation filtering strengthens the test by ensuring assertions only apply to logs with the expected
correlation_id. This prevents false matches against unrelated log entries.docs/users-guide.md (3)
15-35: LGTM!The
no_runattribute correctly prevents doc-test execution for this example that requires a runtime context.
101-107: LGTM!The wording changes correctly remove second-person pronouns whilst maintaining clarity.
672-673: LGTM!The footnote correctly references the implementation files for the client runtime.
src/client/tests.rs (7)
1-16: LGTM!Module documentation, imports, and constants are appropriate for the test module.
18-28: LGTM!The
spawn_listenerhelper is clean and uses.expect()appropriately for test assertions.
30-46: LGTM!The
assert_builder_optionhelper effectively reduces test duplication whilst maintaining readability. Proper cleanup is ensured by awaiting the accept task.
48-105: LGTM!The codec configuration tests comprehensively cover clamping behaviour, defaults, and actual codec round-trip encoding/decoding. The
build_codec_configures_length_delimited_codectest addresses the past review request for validatingLengthDelimitedCodecconfiguration.
107-133: LGTM!The
nodelayandkeepalivesocket option tests correctly verify the options are applied to the underlying TCP socket via the builder.
135-184: LGTM!The
lingerand buffer size tests correctly verify socket options. The>=comparison for buffer sizes is appropriate since the OS may adjust requested values upward.
186-220: LGTM!The
reuseaddrtest is straightforward, and thereuseporttest correctly includes platform guards to exclude unsupported operating systems.src/client/runtime.rs (6)
1-14: LGTM!Module documentation and imports are appropriately structured.
16-44: LGTM!The
WireframeClientstruct is well-designed with appropriate visibility for fields. TheDebugimplementation sensibly excludes I/O types whilst exposing the codec configuration.
46-65: LGTM!The
builder()method correctly provides a specialised entry point for the default serializer, with appropriate#[must_use]annotation.
127-137: LGTM!The
receivemethod correctly handles connection closure by returningClientError::Disconnected. The same error type verification applies as noted forsend.
139-221: LGTM!The
callmethod cleanly composessendandreceive. Thecodec_configandtcp_streamaccessors are appropriately designed, withconst fnwhere possible and#[must_use]annotations.
94-101: The error type compatibility is correct. TheSerializer::serialize()method returnsResult<Vec<u8>, Box<dyn Error + Send + Sync>>, which matches the type expected byClientError::Serialize. No error wrapping or type conversion is required; the code compiles and functions correctly as written.tests/worlds/client_runtime.rs (2)
1-23: LGTM on structure and World setup.The module doc comment is present, the doc comment correctly precedes the derive attributes, and the
ClientRuntimeWorldstruct is well-organised with appropriate optional fields for tracking test state.
64-73: LGTM on client connection setup.The builder usage and codec configuration follow the expected pattern. Error propagation is correct.
src/client/config.rs (5)
15-120: LGTM on ClientCodecConfig implementation.The struct is well-documented with examples, uses fluent setters with
#[must_use], and provides const accessors. Thebuild_codecmethod correctly mapsLengthFormatto the underlying codec configuration.
139-154: LGTM on SocketOptions struct definition.The platform-conditional
reuseportfield is correctly guarded with#[cfg]attributes for supported Unix platforms.
177-311: LGTM on SocketOptions setter methods.All setters follow a consistent fluent pattern with
#[must_use], and each is documented with examples. Thereuseportmethod correctly applies the same#[cfg]guard as the field.
313-328: Decomposition into helper methods addresses complexity concern.The
applymethod delegates to single-responsibility helpers, keeping the cyclomatic complexity manageable. The past CodeScene warning about complexity 9 (at threshold) is mitigated by this structure.
337-352: LGTM on keepalive handling.The implementation correctly uses
socket.set_keepalive(bool)to enable/disable keepalive, then applies the duration viasocket2::SockRefandTcpKeepalive. This resolves the previously flagged type mismatch.
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix: Comment on lines +313 to +352 pub(crate) fn apply(&self, socket: &TcpSocket) -> io::Result<()> {
if let Some(enabled) = self.nodelay {
socket.set_nodelay(enabled)?;
}
if let Some(keepalive) = self.keepalive {
match keepalive {
KeepAliveSetting::Disabled => {
socket.set_keepalive(false)?;
}
KeepAliveSetting::Duration(duration) => {
socket.set_keepalive(true)?;
let sock_ref = SockRef::from(socket);
let config = TcpKeepalive::new().with_time(duration);
sock_ref.set_tcp_keepalive(&config)?;
}
}
}
if let Some(linger) = self.linger {
socket.set_linger(linger.to_option())?;
}
if let Some(size) = self.send_buffer_size {
socket.set_send_buffer_size(size)?;
}
if let Some(size) = self.recv_buffer_size {
socket.set_recv_buffer_size(size)?;
}
if let Some(enabled) = self.reuseaddr {
socket.set_reuseaddr(enabled)?;
}
#[cfg(all(
unix,
not(target_os = "solaris"),
not(target_os = "illumos"),
not(target_os = "cygwin"),
))]
if let Some(enabled) = self.reuseport {
socket.set_reuseport(enabled)?;
}
Ok(())
}❌ New issue: Complex Method |
This comment was marked as resolved.
This comment was marked as resolved.
- Moved ClientCodecConfig from src/client/config.rs to a new module src/client/codec_config.rs for better separation of concerns. - Updated src/client/mod.rs to reflect new module structure. - Removed codec-related code from src/client/config.rs which now focuses solely on socket options. - Adjusted tests and imports accordingly. This refactoring improves code organization and maintainability. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary
Adds a fully configurable Wireframe client runtime, including a builder, codec and socket configuration, error handling, and a runtime driver that mirrors the server's framing/serialization. This enables caller-configurable serializers, frame length, and socket options before establishing a connection, plus end-to-end request/response flows.
Changes
Client runtime
Builder pattern
Configuration
Runtime implementation
Tests
Public API exposure
Usage
Test plan
Notes
🌿 Generated by Terry
ℹ️ Tag @terragon-labs to ask questions and address PR feedback
📎 Task: https://www.terragonlabs.com/task/5ead8d98-3ae6-4da9-8d7f-e581ea2ece4c
Summary by Sourcery
Add a configurable Wireframe client runtime with builder-based codec and socket configuration, expose it via the public API, document its usage, and cover it with unit and behaviour-driven tests.
New Features:
Enhancements:
Documentation:
Tests: