Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 132 additions & 132 deletions docs/complexity-antipatterns-and-refactoring-strategies.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct PartialMessage {

The use of `dashmap::DashMap` allows for lock-free reads and sharded writes,
providing efficient and concurrent access to the re-assembly buffers without
blocking the entire connection task. 1
blocking the entire connection task.

## 4. Public API: The `FragmentStrategy` Trait

Expand Down
11 changes: 6 additions & 5 deletions docs/mocking-network-outages-in-rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ With this change, `client_handler` no longer assumes a real network `TcpStream`;
we can pass in any in-memory or mock stream for testing. **Importantly**, the
production code doesn’t lose functionality – we still create actual TCP
listeners/streams, but we hand off to the generic handler. This refactor
maintains the same behavior while enabling injection of test streams.
maintains the same behaviour while enabling injection of test streams.

*Example – generic handler signature:*

Expand Down Expand Up @@ -227,7 +227,7 @@ but on generic `reader`/`writer`. This refactoring sets the stage for injecting
With the transport abstracted, we can create **dummy streams** to simulate
various network outage scenarios. Tokio’s testing utilities include
`tokio_test::io::Builder`, which allows building an object that implements
`AsyncRead` and `AsyncWrite` with predetermined behavior. We can script a
`AsyncRead` and `AsyncWrite` with predetermined behaviour. We can script a
sequence of reads/writes and even inject errors.

For example, the Tokio documentation demonstrates using `Builder` to simulate a
Expand Down Expand Up @@ -570,7 +570,8 @@ explicit mocking might be useful. The `mockall` crate can generate mocks for our
abstractions. For example, if we had defined a trait
`trait Transport: AsyncRead + AsyncWrite + Unpin {}` (or a trait with specific
async methods for read/write), we could use `mockall` to create a
`MockTransport` and program its behavior (return errors on certain calls, etc.).
`MockTransport` and program its behaviour (return errors on certain calls,
etc.).

However, mocking `AsyncRead/Write` directly can be complex. An easier target for
mocking might be higher-level components:
Expand Down Expand Up @@ -608,7 +609,7 @@ mocking might be higher-level components:
don’t invoke the real DB or commands at all – the mock could simply return a
simple “OK” response transaction when called. Then we only simulate the
network failing on sending that response. Such a mock ensures our test is
laser-focused on networking behavior.
laser-focused on networking behaviour.

In summary, **use** `mockall` **when stubbing out parts of the system that are
not the primary target of the test**. For testing network outages in `mxd`, the
Expand Down Expand Up @@ -654,7 +655,7 @@ demonstrated how to simulate timeouts, abrupt disconnects, and I/O errors for
both reads and writes. With parameterized tests and careful use of mocks, the
server’s resilience under adverse network conditions can be validated
thoroughly. This not only prevents regressions but also documents the intended
behavior (for example, that a timeout should result in a specific error code to
behaviour (for example, that a timeout should result in a specific error code to
the client, or that an EOF is treated as a graceful shutdown).

**In conclusion**, testing for network outages in async Rust requires a mix of
Expand Down
6 changes: 3 additions & 3 deletions docs/multi-packet-and-streaming-responses-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ response feature. The core philosophy is to enable this complex functionality
through a simple, declarative, and ergonomic API. By embracing modern
asynchronous Rust patterns, we will avoid the complexities of imperative,
sink-based APIs and provide a unified handler model that is both powerful for
streaming and simple for single-frame replies. 1
streaming and simple for single-frame replies.

This feature is a key component of the "Road to Wireframe 1.0," working in
concert with asynchronous push messaging and fragmentation to create a fully
Expand Down Expand Up @@ -227,12 +227,12 @@ If the stream yields an `Err(WireframeError<E>)`, the connection actor will:
The design is inherently cancellation-safe. The `select!` macro in the
connection actor will drop the `FrameStream` future if another branch (e.g., a
shutdown signal) completes first. Because `StreamExt::next()` is
cancellation-safe, no frames will be lost; the stream will simply be dropped. 12
cancellation-safe, no frames will be lost; the stream will simply be dropped.

Similarly, if a handler panics or returns early, the `Stream` object it created
is simply dropped. The connection actor will see the stream end as if it had
completed normally, ensuring no resources are leaked and the connection does not
hang. 17
hang.

## 7. Synergy with Other 1.0 Features

Expand Down
10 changes: 5 additions & 5 deletions docs/rust-binary-router-library-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,14 @@ network protocols, offering insights into effective abstractions.
Although designed for RPC, its approach of defining service schemas directly
in Rust code (using the `#[tarpc::service]` attribute to generate service
traits and client/server boilerplate) is an interesting parallel to
"wireframe's" goal of reducing boilerplate for message handlers.20 Features
like pluggable transports and serde serialization further highlight its modern
"wireframe's" goal of reducing boilerplate for message handlers. Features like
pluggable transports and serde serialization further highlight its modern
Comment on lines +157 to +158
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Capitalise the proper noun “Serde”.

Within Rust documentation the crate is normally referred to as “Serde”. Using the lowercase form can read as a common noun rather than the crate name.

- pluggable transports and serde serialization further highlight its modern
+ pluggable transports and Serde serialisation further highlight its modern
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"wireframe's" goal of reducing boilerplate for message handlers. Features like
pluggable transports and serde serialization further highlight its modern
"wireframe's" goal of reducing boilerplate for message handlers. Features like
pluggable transports and Serde serialisation further highlight its modern
🤖 Prompt for AI Agents
In docs/rust-binary-router-library-design.md at lines 157 to 158, the word
"serde" should be capitalized to "Serde" to correctly refer to the Rust crate as
a proper noun. Update the text to use "Serde" instead of "serde" to align with
Rust documentation conventions.

design.

A clear pattern emerges from these libraries: the use of derive macros and
trait-based designs is a prevalent and effective strategy in Rust for
simplifying protocol handling and reducing boilerplate code. Both `bin-proto` 14
and `protocol` 16 leverage custom derives to generate (de)serialization logic
simplifying protocol handling and reducing boilerplate code. Both `bin-proto`
and `protocol` leverage custom derives to generate (de)serialization logic
directly from struct and enum definitions. This is a proven pattern for
enhancing developer ergonomics and reducing the likelihood of manual
implementation errors. "wireframe" should strongly consider adopting a similar
Expand Down Expand Up @@ -1348,7 +1348,7 @@ simplicity; "wireframe" aims for similar illustrative power with its examples.

A primary motivation for "wireframe" is to reduce the inherent source code
complexity often encountered when developing systems that communicate over
custom binary protocols. The inaccessibility of the `leynos/mxd` repository 7
custom binary protocols. The inaccessibility of the `leynos/mxd` repository
prevents a direct before-and-after comparison, but we can identify common
sources of complexity in such projects and articulate how "wireframe's" design
choices aim to mitigate them.
Expand Down
Loading