Skip to content

Commit 43be1fc

Browse files
committed
Merge branch 'master' into dev-iocp4
2 parents 7af988e + 4f6f3f1 commit 43be1fc

File tree

13 files changed

+458
-75
lines changed

13 files changed

+458
-75
lines changed

README.md

Lines changed: 107 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,104 @@
88
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "Average time to resolve an issue")
99
[![Percentage of issues still open](http://isitmaintained.com/badge/open/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "Percentage of issues still open")
1010

11-
The `open-coroutine` is a simple, efficient and generic stackful-coroutine library.
11+
The `open-coroutine` is a simple, efficient and generic stackfull-coroutine library, you can use this as a performance
12+
replacement for IO thread pools, see [why better](core/docs/en/why-better.md).
1213

1314
English | [中文](README_ZH.md)
1415

1516
## 🚀 Features
1617

17-
- [x] Preemptive(`not supported in windows`): even if the coroutine enters a dead loop, it can still be seized, see [example](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/preemptive.rs);
18-
- [x] Hook: you are free to use most of the slow syscall in coroutine, see supported syscall on [unix](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/unix.rs)/[windows](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/windows.rs);
19-
- [x] Scalable: the size of the coroutine stack supports unlimited expansion without the cost of copying stack, and immediately shrinks to the original size after use, see [example](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/scalable_stack.rs);
20-
- [x] io_uring(`only in linux`): supports and is compatible with io_uring in terms of local file IO and network IO. If it's not supported on your system, it will fall back to non-blocking IO;
18+
- [x] Preemptive(`not supported in windows`): even if the coroutine enters a dead loop, it can still be seized,
19+
see [example](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/preemptive.rs);
20+
- [x] Hook: you are free to use most of the slow syscall in coroutine, see supported syscall
21+
on [unix](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/unix.rs)/[windows](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/windows.rs);
22+
- [x] Scalable: the size of the coroutine stack supports unlimited expansion without the cost of copying stack, and
23+
immediately shrinks to the original size after use,
24+
see [example](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/scalable_stack.rs);
25+
- [x] io_uring(`only in linux`): supports and is compatible with io_uring in terms of local file IO and network IO. If
26+
it's not supported on your system, it will fall back to non-blocking IO;
2127
- [x] Priority: support custom task priority, note that coroutine priority is not open to users;
2228
- [x] Work Steal: internally using a lock free work steal queue;
23-
- [x] Compatibility: the implementation of open-coroutine is no async, but it is compatible with async, which means you can use this crate in `tokio/async-std/smol/...`;
29+
- [x] Compatibility: the implementation of open-coroutine is no async, but it is compatible with async, which means you
30+
can use this crate in `tokio/async-std/smol/...`;
2431
- [x] Platforms: running on Linux, macOS and Windows;
2532

2633
## 🕊 Roadmap
2734

35+
- [ ] add docs;
36+
- [ ] add
37+
performance [benchmark](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview);
2838
- [ ] cancel coroutine/task;
2939
- [ ] add metrics;
3040
- [ ] add synchronization toolkit;
3141
- [ ] support and compatibility for AF_XDP socket;
3242

43+
## 🏠 Architecture
44+
45+
```mermaid
46+
graph TD
47+
subgraph ApplicationFramework
48+
Tower
49+
Actix-Web
50+
Rocket
51+
warp
52+
axum
53+
end
54+
subgraph MessageQueue
55+
RocketMQ
56+
Pulsar
57+
end
58+
subgraph RemoteProcedureCall
59+
Dubbo
60+
Tonic
61+
gRPC-rs
62+
Volo
63+
end
64+
subgraph Database
65+
MySQL
66+
Oracle
67+
end
68+
subgraph NetworkFramework
69+
Tokio
70+
monoio
71+
async-std
72+
smol
73+
end
74+
subgraph open-coroutine-architecture
75+
subgraph core
76+
Preemptive
77+
ScalableStack
78+
WorkSteal
79+
Priority
80+
end
81+
subgraph hook
82+
HookSyscall
83+
end
84+
subgraph macros
85+
open-coroutine::main
86+
end
87+
subgraph open-coroutine
88+
end
89+
hook -->|depends on| core
90+
open-coroutine -->|link| hook
91+
open-coroutine -->|depends on| macros
92+
end
93+
subgraph OperationSystem
94+
Linux
95+
macOS
96+
Windows
97+
end
98+
ApplicationFramework -->|maybe depends on| RemoteProcedureCall
99+
ApplicationFramework -->|maybe depends on| MessageQueue
100+
ApplicationFramework -->|maybe depends on| Database
101+
MessageQueue -->|depends on| NetworkFramework
102+
RemoteProcedureCall -->|depends on| NetworkFramework
103+
NetworkFramework -->|runs on| OperationSystem
104+
NetworkFramework -->|can depends on| open-coroutine-architecture
105+
Database -->|runs on| OperationSystem
106+
open-coroutine-architecture -->|runs on| OperationSystem
107+
```
108+
33109
## 📖 Quick Start
34110

35111
### step1: add dependency to your Cargo.toml
@@ -60,7 +136,9 @@ fn main() {
60136
}
61137
```
62138

63-
### create a task with priority(optional)
139+
## 🪽 Advanced Usage
140+
141+
### create a task with priority
64142

65143
```rust
66144
#[open_coroutine::main]
@@ -71,7 +149,7 @@ fn main() {
71149
}
72150
```
73151

74-
### wait until the task is completed or timed out(optional)
152+
### wait until the task is completed or timed out
75153

76154
```rust
77155
#[open_coroutine::main]
@@ -83,7 +161,7 @@ fn main() {
83161
}
84162
```
85163

86-
### scalable stack(optional)
164+
### scalable stack
87165

88166
```rust
89167
#[open_coroutine::main]
@@ -109,6 +187,26 @@ fn main() {
109187
## ⚓ Learn More
110188

111189
- [Coroutine Overview](core/docs/en/coroutine.md)
190+
- [Scalable Stack Overview](core/docs/en/scalable-stack.md)
112191
- [Monitor Overview](core/docs/en/monitor.md)
113192

114193
[我有故事,你有酒吗?](https://github.com/acl-dev/open-coroutine-docs)
194+
195+
## 👍 Credits
196+
197+
This crate was inspired by the following projects:
198+
199+
- [acl](https://github.com/acl-dev/acl)
200+
- [coost](https://github.com/idealvin/coost)
201+
- [golang](https://github.com/golang/go)
202+
- [stacker](https://github.com/rust-lang/stacker)
203+
- [monoio](https://github.com/bytedance/monoio)
204+
- [compio](https://github.com/compio-rs/compio)
205+
- [may](https://github.com/Xudong-Huang/may)
206+
207+
Thanks to those who have provided assistance:
208+
209+
[![Amanieu](https://images.weserv.nl/?url=avatars.githubusercontent.com/Amanieu?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/Amanieu)
210+
[![bjorn3](https://images.weserv.nl/?url=avatars.githubusercontent.com/bjorn3?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/bjorn3)
211+
[![workingjubilee](https://images.weserv.nl/?url=avatars.githubusercontent.com/workingjubilee?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/workingjubilee)
212+
[![Noratrieb](https://images.weserv.nl/?url=avatars.githubusercontent.com/Noratrieb?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/Noratrieb)

README_ZH.md

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "解决issue的平均时间")
99
[![Percentage of issues still open](http://isitmaintained.com/badge/open/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "仍未关闭issue的百分比")
1010

11-
`open-coroutine`是一个简单、高效、通用的有栈协程库
11+
`open-coroutine`是一个简单、高效、通用的有栈协程库,您可以将其用作IO线程池的性能替代,查看[为什么更好](core/docs/en/why-better.md).
1212

1313
[English](README.md) | 中文
1414

1515
## 🚀 当前特性
1616

17-
- [x] 抢占调度(`不支持windows`): 即使协程进入死循环,它仍能被抢占,查看[例子](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/preemptive.rs);
18-
- [x] Hook: 您可以在协程中自由使用大多数慢系统调用,查看支持的系统调用[unix](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/unix.rs)/[windows](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/windows.rs);
19-
- [x] 可伸缩栈: 协程栈的大小支持无限制扩容而没有复制堆栈的开销,查看[例子](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/scalable_stack.rs);
17+
- [x] 抢占调度(`不支持windows`):
18+
即使协程进入死循环,它仍能被抢占,查看[例子](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/preemptive.rs);
19+
- [x] Hook:
20+
您可以在协程中自由使用大多数慢系统调用,查看支持的系统调用[unix](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/unix.rs)/[windows](https://github.com/acl-dev/open-coroutine/blob/master/hook/src/syscall/windows.rs);
21+
- [x] 可伸缩栈:
22+
协程栈的大小支持无限制扩容而没有复制堆栈的开销,查看[例子](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/scalable_stack.rs);
2023
- [x] io_uring(`只支持linux`): 在本地文件IO和网络IO方面支持并兼容io_uring。如果您的系统不支持,它将回退到NIO;
2124
- [x] 优先级: 支持自定义任务优先级,注意协程优先级未对用户开放;
2225
- [x] 任务窃取: 内部使用无锁任务窃取队列;
@@ -25,11 +28,80 @@
2528

2629
## 🕊 未来计划
2730

31+
- [ ] 完善文档;
32+
- [ ]
33+
增加性能[基准测试](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview);
2834
- [ ] 取消协程/任务;
2935
- [ ] 增加性能指标;
3036
- [ ] 增加并发工具包;
3137
- [ ] 支持AF_XDP套接字;
3238

39+
## 🏠 架构设计
40+
41+
```mermaid
42+
graph TD
43+
subgraph ApplicationFramework
44+
Tower
45+
Actix-Web
46+
Rocket
47+
warp
48+
axum
49+
end
50+
subgraph MessageQueue
51+
RocketMQ
52+
Pulsar
53+
end
54+
subgraph RemoteProcedureCall
55+
Dubbo
56+
Tonic
57+
gRPC-rs
58+
Volo
59+
end
60+
subgraph Database
61+
MySQL
62+
Oracle
63+
end
64+
subgraph NetworkFramework
65+
Tokio
66+
monoio
67+
async-std
68+
smol
69+
end
70+
subgraph open-coroutine-architecture
71+
subgraph core
72+
Preemptive
73+
ScalableStack
74+
WorkSteal
75+
Priority
76+
end
77+
subgraph hook
78+
HookSyscall
79+
end
80+
subgraph macros
81+
open-coroutine::main
82+
end
83+
subgraph open-coroutine
84+
end
85+
hook -->|depends on| core
86+
open-coroutine -->|link| hook
87+
open-coroutine -->|depends on| macros
88+
end
89+
subgraph OperationSystem
90+
Linux
91+
macOS
92+
Windows
93+
end
94+
ApplicationFramework -->|maybe depends on| RemoteProcedureCall
95+
ApplicationFramework -->|maybe depends on| MessageQueue
96+
ApplicationFramework -->|maybe depends on| Database
97+
MessageQueue -->|depends on| NetworkFramework
98+
RemoteProcedureCall -->|depends on| NetworkFramework
99+
NetworkFramework -->|runs on| OperationSystem
100+
NetworkFramework -->|can depends on| open-coroutine-architecture
101+
Database -->|runs on| OperationSystem
102+
open-coroutine-architecture -->|runs on| OperationSystem
103+
```
104+
33105
## 📖 快速接入
34106

35107
### step1: 在你的Cargo.toml中添加依赖
@@ -60,7 +132,9 @@ fn main() {
60132
}
61133
```
62134

63-
### 创建具有优先级的任务(可选)
135+
## 🪽 进阶使用
136+
137+
### 创建具有优先级的任务
64138

65139
```rust
66140
#[open_coroutine::main]
@@ -71,7 +145,7 @@ fn main() {
71145
}
72146
```
73147

74-
### 等待任务完成或超时(可选)
148+
### 等待任务完成或超时
75149

76150
```rust
77151
#[open_coroutine::main]
@@ -83,7 +157,7 @@ fn main() {
83157
}
84158
```
85159

86-
### 扩容栈(可选)
160+
### 可伸缩栈
87161

88162
```rust
89163
#[open_coroutine::main]
@@ -112,3 +186,22 @@ fn main() {
112186
- [语言选择](docs/cn/why-rust.md)
113187

114188
[我有故事,你有酒吗?](https://github.com/acl-dev/open-coroutine-docs)
189+
190+
## 👍 鸣谢
191+
192+
这个crate的灵感来自以下项目:
193+
194+
- [acl](https://github.com/acl-dev/acl)
195+
- [coost](https://github.com/idealvin/coost)
196+
- [golang](https://github.com/golang/go)
197+
- [stacker](https://github.com/rust-lang/stacker)
198+
- [monoio](https://github.com/bytedance/monoio)
199+
- [compio](https://github.com/compio-rs/compio)
200+
- [may](https://github.com/Xudong-Huang/may)
201+
202+
感谢那些提供帮助的人:
203+
204+
[![Amanieu](https://images.weserv.nl/?url=avatars.githubusercontent.com/Amanieu?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/Amanieu)
205+
[![bjorn3](https://images.weserv.nl/?url=avatars.githubusercontent.com/bjorn3?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/bjorn3)
206+
[![workingjubilee](https://images.weserv.nl/?url=avatars.githubusercontent.com/workingjubilee?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/workingjubilee)
207+
[![Noratrieb](https://images.weserv.nl/?url=avatars.githubusercontent.com/Noratrieb?v=4&h=79&w=79&fit=cover&mask=circle&maxage=7d)](https://github.com/Noratrieb)

core/docs/en/coroutine.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,24 @@ The above is excerpted from [corosensei](https://github.com/Amanieu/corosensei).
4949

5050
## Coroutine VS Thread
5151

52-
| | coroutine | thread |
53-
|-------------------|-----------|---------|
54-
| switch efficiency | ✅ Higher | ❌ High |
55-
| memory efficiency | KB/MB | KB/MB |
56-
| scheduled by OS |||
57-
| stack grow |||
52+
| | coroutine | thread |
53+
|-------------------|----------------|----------|
54+
| switch efficiency | ✅ Higher | ❌ High |
55+
| memory usage | ✅ Bytes/KB/MB | ❌ KB/MB |
56+
| scheduled by OS | | |
57+
| stack grow | | |
5858

5959
## Stackfull VS Stackless
6060

6161
| | stackfull | stackless |
6262
|-------------------|-----------|-----------|
6363
| switch efficiency | ❌ High | ✅ Higher |
64-
| memory efficiency | ❌ KB/MB | ✅ Bytes |
64+
| memory usage | ❌ KB/MB | ✅ Bytes |
6565
| limitations | ✅ Few | ❌ Many |
6666

6767
In general, if the requirements for resource utilization and switching performance are not very strict, using a
68-
stackfull approach would be more convenient and the code would be easier to maintain.
68+
stackfull approach would be more convenient and the code would be easier to maintain. So, `open-coroutine` chooses the
69+
stackfull coroutine.
6970

7071
## State in open-coroutine
7172

@@ -112,3 +113,5 @@ coroutines may flow between multiple threads which makes `ThreadLocal` invalid.
112113
introduce `CoroutineLocal`. It's similar to `ThreadLocal`'s approach of providing replicas, but `CoroutineLocal` has
113114
upgraded the replicas to the coroutine level, which means each coroutine has its own local variables. These local
114115
variables will be dropped together when the coroutine is dropped.
116+
117+
## [Scalable Stack Overview](scalable-stack.md)

core/docs/en/monitor.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ fn main() -> std::io::Result<()> {
3333
// is not enabled, it will remain stuck in a dead loop after resume.
3434
let mut coroutine: Coroutine<(), (), ()> = co!(|_, ()| { loop {} })?;
3535
assert_eq!(CoroutineState::Suspend((), 0), coroutine.resume()?);
36+
// will never reach if the preemptive feature is not enabled
3637
assert_eq!(CoroutineState::Suspend((), 0), coroutine.state());
3738
Ok(())
3839
}
@@ -43,7 +44,7 @@ fn main() -> std::io::Result<()> {
4344
The `monitor` mod implements the `preemptive` feature for open-coroutine, which allows the coroutine to be preempted
4445
when it is running for a long time.
4546

46-
## Why preempt
47+
## Why preempt?
4748

4849
After a `Coroutine::resume_with`, a coroutine may occupy the scheduling thread for a long time, thereby slowing down
4950
other coroutines scheduled by that scheduling thread. To solve this problem, we introduce preemptive scheduling, which

0 commit comments

Comments
 (0)