Skip to content

Commit 9ce6efe

Browse files
committed
docs(volo/motore): add some content and some small fix
1 parent 99d1b26 commit 9ce6efe

File tree

4 files changed

+73
-24
lines changed

4 files changed

+73
-24
lines changed

content/en/docs/volo/motore/getting_started.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,31 @@ async fn run_builder() {
242242
println!("Final context steps: {}", cx.processing_steps); // Will print 1
243243
}
244244

245+
// Fun fact: `ServiceBuilder` also implements the `Layer` trait, which means
246+
// you can nest one `ServiceBuilder` inside another `ServiceBuilder`'s `layer` method:
247+
// --- Suppose we have a bunch of middleware ---
248+
// struct LogLayer;
249+
// struct TimeoutLayer;
250+
// struct AuthLayer;
251+
// struct MetricsLayer;
252+
// struct MyCoreService;
253+
//
254+
// 1. We can create a reusable "authentication" middleware stack
255+
// let auth_stack = ServiceBuilder::new()
256+
// .layer(MetricsLayer)
257+
// .layer(AuthLayer);
258+
//
259+
// 2. Now, `auth_stack` is a `ServiceBuilder<...>`
260+
// Since `ServiceBuilder` implements `Layer`,
261+
// we can use the entire `auth_stack` as a single `Layer`!
262+
//
263+
// 3. Use `auth_stack` in our main `ServiceBuilder`
264+
// let final_service = ServiceBuilder::new()
265+
// .layer(LogLayer)
266+
// .layer(auth_stack) // <-- This step works precisely because `ServiceBuilder` implements `Layer`
267+
// .layer(TimeoutLayer)
268+
// .service(MyCoreService);
269+
245270
// -----------------------------------------------------------------------------
246271
// 5. Helper Utility: `service_fn`
247272
// -----------------------------------------------------------------------------

content/en/docs/volo/motore/motore_volo_relationship.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ keywords: ["Motore", "Volo", "Relationship", "Middleware", "RPC"]
66
description: "Motore provides the core middleware abstraction for Volo. Volo uses Motore as the foundation of its core middleware abstraction layer, on top of which RPC-related functions and implementations are built."
77
---
88

9-
Understanding the relationship between them is crucial for in-depth use of Volo, framework extension, or developing custom middleware.
9+
Understanding the relationship between them is crucial for in-depth use of Volo (such as framework extension, developing custom middleware, etc.).
1010

11-
In simple terms: **Motore defines the two general and core asynchronous middleware abstract interfaces, `Service` and `Layer`, while Volo is the main user of these abstract interfaces and the implementer in specific scenarios (RPC)**.
11+
In simple terms: **Motore defines the two general and core asynchronous middleware abstract interfaces, `Service` and `Layer`, while Volo is the user of these abstract interfaces and the implementer in specific scenarios (RPC)**.
1212

1313
Motore is more general and can theoretically be used in any place that requires asynchronous service abstraction. Volo is more specific, focusing on the RPC field and utilizing Motore's abstraction to implement RPC-specific functions.
1414

@@ -21,15 +21,15 @@ Motore is an independent Rust crate ([cloudwego/motore](https://github.com/cloud
2121
Motore mainly defines two core Traits:
2222

2323
1. **`Service<Cx, Request>`**:
24-
* Represents a functional unit that processes requests and asynchronously returns a `Result<Response, Error>`.
25-
* This is the most basic component in Motore and can represent a client, a server, or the middleware itself.
26-
* Its core is the `async fn call(&self, cx: &mut Cx, req: Request) -> Result<Self::Response, Self::Error>` method. It receives a context `Cx` and a request `Request`, and asynchronously returns the result.
24+
* Represents a functional unit that processes requests and asynchronously returns a `Result<Response, Error>`.
25+
* This is the most basic component in Motore and can represent a client, a server, or the middleware itself.
26+
* Its core is the `async fn call(&self, cx: &mut Cx, req: Request) -> Result<Self::Response, Self::Error>` method. It receives a context `Cx` and a request `Request`, and asynchronously returns the result.
2727

2828
2. **`Layer<S>`**:
29-
* Represents a "decorator" or "factory" used to wrap and enhance a `Service`.
30-
* It receives an inner `Service` (generic `S`) and returns a new, wrapped `Service` (`Self::Service`).
31-
* `Layer` itself does not directly handle requests but is used to build and compose `Service` chains (i.e., middleware stacks).
32-
* Its core is the `fn layer(self, inner: S) -> Self::Service` method.
29+
* Represents a "decorator" or "factory" used to wrap and enhance a `Service`.
30+
* It receives an inner `Service` (generic `S`) and returns a new, wrapped `Service` (`Self::Service`).
31+
* `Layer` itself does not directly handle requests but is used to build and compose `Service` chains (i.e., middleware stacks).
32+
* Its core is the `fn layer(self, inner: S) -> Self::Service` method.
3333

3434
Motore aims to provide a protocol-agnostic, reusable middleware infrastructure. It focuses on the abstraction itself, rather than a framework for a specific application domain like RPC (as Volo is), but Motore can serve as a foundation for building such frameworks.
3535

@@ -44,23 +44,23 @@ Motore also provides some auxiliary tools, such as `ServiceBuilder` for chaining
4444
Volo is a full-featured RPC framework that supports Thrift and gRPC. Volo **directly depends on and is deeply integrated with Motore** as the foundation of its internal middleware system.
4545

4646
1. **Dependency and Re-export**:
47-
* Volo directly depends on the `motore` crate in its `Cargo.toml`.
48-
* Volo **re-exports** Motore's core Traits at the entry point of its library (`volo/src/lib.rs`): `pub use motore::{Service, layer, Layer, service};`. When you use `volo::Service` or `volo::Layer` in a Volo project, you are **actually using the Traits from Motore**.
47+
* Volo directly depends on the `motore` crate in its `Cargo.toml`.
48+
* Volo **re-exports** Motore's core Traits at the entry point of its library (`volo/src/lib.rs`): `pub use motore::{Service, layer, Layer, service};`. When you use `volo::Service` or `volo::Layer` in a Volo project, you are **actually using the Traits from Motore**.
4949

5050
2. **Specific Implementation**:
51-
* The Volo framework extensively uses the abstractions provided by Motore to build its functionality. For example:
52-
* Load balancing (`LoadBalanceLayer`) is a component that implements Motore's `Layer`.
53-
* Features like timeout control, logging, and metrics collection can be integrated by implementing Motore's `Layer`.
54-
* The RPC service handling logic (Handler) written by the end-user, as well as the client-side calling logic generated by the framework, will be wrapped into a form that conforms to the Motore `Service` interface.
55-
* Volo provides many `Layer` **implementations** that are **specific to the RPC scenario**, such as handling Thrift or gRPC protocol details, service discovery integration, etc. These implementations all follow the `Layer` interface defined by Motore.
51+
* The Volo framework extensively uses the abstractions provided by Motore to build its functionality. For example:
52+
* Load balancing (`LoadBalanceLayer`) is a component that implements Motore's `Layer`.
53+
* Features like timeout control, logging, and metrics collection can be integrated by implementing Motore's `Layer`.
54+
* The RPC service handling logic (Handler) written by the end-user, as well as the client-side calling logic generated by the framework, will be wrapped into a form that conforms to the Motore `Service` interface.
55+
* Volo provides many `Layer` **implementations** that are **specific to the RPC scenario**, such as handling Thrift or gRPC protocol details, service discovery integration, etc. These implementations all follow the `Layer` interface defined by Motore.
5656

5757
3. **User Interaction**:
58-
* Volo users generally configure and add middleware through the APIs provided by `Client::builder()` or `Server::new()`. These APIs internally use `motore::ServiceBuilder` or the low-level `motore::layer::Stack` to apply the `Layer`s provided by the user to the `Service`.
59-
* If users need to write custom middleware, they also need to implement the `motore::Layer` Trait (or directly implement `motore::Service` to wrap another Service).
58+
* Volo users generally configure and add middleware through the APIs provided by `Client::builder()` or `Server::new()`. These APIs internally use `motore::ServiceBuilder` or the low-level `motore::layer::Stack` to apply the `Layer`s provided by the user to the `Service`.
59+
* If users need to write custom middleware, they also need to implement the `motore::Layer` Trait (or directly implement `motore::Service` to wrap another Service).
6060

6161
## Why is Motore needed?
6262

6363
Separating the core abstraction (Motore) from the framework implementation (Volo) brings several benefits:
6464

6565
1. **Modularity and Reusability**: The abstractions and some basic Layers (like timeout) defined by Motore are generic and can be used by projects other than Volo to write middleware and services.
66-
2. **Separation of Concerns**: Motore focuses on providing stable, efficient, and ergonomic core abstractions. Volo, on the other hand, focuses on the business logic and protocol details of the RPC framework.
66+
2. **Separation of Concerns**: Motore focuses on providing stable, efficient, and ergonomic core abstractions. Volo, on the other hand, focuses on the business logic and protocol details of the RPC framework.

content/zh/docs/volo/motore/getting_started.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,30 @@ async fn run_builder() {
240240
println!("Final context steps: {}", cx.processing_steps); // 将打印 1
241241
}
242242

243+
// 讲个好玩的,ServiceBuilder 也实现了 Layer trait,所以能把一个 ServiceBuilder 放在另外一个 ServiceBuilder 的 layer 方法里面:
244+
// --- 有一堆中间件 ---
245+
// struct LogLayer;
246+
// struct TimeoutLayer;
247+
// struct AuthLayer;
248+
// struct MetricsLayer;
249+
// struct MyCoreService;
250+
//
251+
// 1. 我们可以创建一个可复用的 "鉴权" 中间件栈
252+
// let auth_stack = ServiceBuilder::new()
253+
// .layer(MetricsLayer)
254+
// .layer(AuthLayer);
255+
//
256+
// 2. 现在,auth_stack 是一个 ServiceBuilder<...>
257+
// 因为 ServiceBuilder 实现了 Layer,
258+
// 所以我们可以把整个 auth_stack 当作一个 Layer 来使用!
259+
//
260+
// 3. 在我们的主 ServiceBuilder 中使用 auth_stack
261+
// let final_service = ServiceBuilder::new()
262+
// .layer(LogLayer)
263+
// .layer(auth_stack) // <-- 这一步之所以能成功,就是因为 ServiceBuilder 实现了 Layer
264+
// .layer(TimeoutLayer)
265+
// .service(MyCoreService);
266+
243267
// -----------------------------------------------------------------------------
244268
// 5. 辅助工具:`service_fn`
245269
// -----------------------------------------------------------------------------

content/zh/docs/volo/motore/motore_volo_relationship.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ keywords: ["Motore", "Volo", "关系", "中间件", "RPC"]
66
description: "Motore 为 Volo 提供了核心的中间件抽象,Volo 使用 Motore 作为其核心中间件抽象层的基础,在此之上构建了 RPC 相关的功能和实现。"
77
---
88

9-
理解它们之间的关系对于深入使用 Volo、进行框架扩展或开发自定义中间件至关重要
9+
理解它们之间的关系对深入使用 Volo(进行框架扩展、开发自定义中间件 等等)至关重要
1010

11-
简单来说:**Motore 定义了 `Service``Layer` 这两个通用的、核心的异步中间件抽象接口,而 Volo 是这些抽象接口的主要使用者和特定场景(RPC)下的实现者**
11+
简单来说:**Motore 定义了 `Service``Layer` 这两个通用的、核心的异步中间件抽象接口,而 Volo 是这些抽象接口的使用者和特定场景(RPC)下的实现者**
1212

1313
Motore 更通用,理论上可用于任何需要异步服务抽象的地方。Volo 则更具体地专注于 RPC 领域,利用 Motore 的抽象来实现 RPC 特有的功能。
1414

15-
可以将 Motore 视为 Volo 中间件系统的"骨架",Volo 本身为 "骨架" 注入了 "血肉"(实现 RPC 所需的框架层面的组件和逻辑),用户最终在 Volo 上去填充具体的业务逻辑。
15+
可以将 Motore 视为 Volo 中间件系统的 "骨架",Volo 本身为 "骨架" 注入了 "血肉"(实现 RPC 所需的框架层面的组件和逻辑),用户最终在 Volo 上去填充具体的业务逻辑。
1616

1717
## Motore: 核心抽象层
1818

19-
Motore 是一个独立的 Rust crate ([cloudwego/motore](https://github.com/cloudwego/motore)),其设计目标是提供一套简洁、高效且符合人体工程学的异步中间件抽象。它受到了业界广泛使用的 [Tower](https://github.com/tower-rs/tower) 库的启发,但在设计上利用了 Rust 最新的 **AFIT (async fn in trait)****RPITIT (return position impl trait in trait)** 特性。
19+
Motore 是一个独立的 Rust crate ([cloudwego/motore](https://github.com/cloudwego/motore)),其设计目标是提供一套简洁、高效且符合人体工程学的异步中间件抽象。虽然它受到了业界广泛使用的 [Tower](https://github.com/tower-rs/tower) 库的启发,但在设计上它利用了 Rust 最新的 **AFIT (async fn in trait)****RPITIT (return position impl trait in trait)** 特性。
2020

2121
Motore 主要定义了两个核心 Trait:
2222

@@ -48,7 +48,7 @@ Volo 是一个功能完备的 RPC 框架,支持 Thrift 和 gRPC。Volo **直
4848
* Volo 在其库的入口(`volo/src/lib.rs`**重新导出**了 Motore 的核心 Trait:`pub use motore::{Service, layer, Layer, service};`。当你在 Volo 项目中使用 `volo::Service``volo::Layer` 时,你**实际上用的就是 Motore 那边的 Trait**
4949

5050
2. **具体实现**:
51-
* Volo 框架内部大量使用了 Motore 提供的抽象来构建其功能。例如:
51+
* Volo 框架内部大量使用 Motore 提供的抽象来构建其功能。例如:
5252
* 负载均衡 (`LoadBalanceLayer`) 是一个实现了 Motore `Layer` 的组件。
5353
* 超时控制、日志记录、指标收集等功能都可以通过实现 Motore `Layer` 来集成。
5454
* 最终用户编写的 RPC 服务处理逻辑(Handler),以及框架生成的客户端调用逻辑,都会被包装成符合 Motore `Service` 接口的形式。

0 commit comments

Comments
 (0)