2 个版本
0.1.2 | 2020 年 4 月 19 日 |
---|---|
0.1.0 | 2020 年 4 月 17 日 |
#1873 in 异步
26KB
416 行
异步 Rust 的外部执行器
本项目旨在提供简单的执行器,帮助将异步 Rust 代码运行到外部事件循环中。例如,当您开发包含 Rust 中的异步代码的动态链接库,并希望在不同的执行环境中运行它时,这可能很有用。
使用方法
Rust 端,您应该将 extern_executor
添加为依赖项到您的 cdylib
库,并使用 spawn()
函数运行 futures,如下所示
use extern_executor::spawn;
spawn(async {
// your awaits
});
C 端,您应该使用您首选的事件循环 API 实现执行器的驱动程序。例如,当使用 libuv 时,它可能看起来像这样
#include <uv.h>
#include <rust_async_executor.h>
static void task_wake(RustAsyncExecutorExternTask data) {
uv_async_t* handle = data;
// wakeup uv's async task
uv_async_send(handle);
}
static void task_poll(uv_async_t* handle) {
// poll internal task until task complete
if (!rust_async_executor_poll(handle->data)) {
// drop internal task when task complete
rust_async_executor_drop(handle->data);
// drop uv's async task handle
uv_close((uv_handle_t*)handle, NULL);
}
}
static RustAsyncExecutorExternTask
task_new(RustAsyncExecutorUserData data) {
uv_loop_t* loop = data;
// crate and initialize uv's async task handle
uv_async_t* handle = malloc(sizeof(uv_async_t));
uv_async_init(loop, handle, task_poll);
return handle;
}
static void task_run(RustAsyncExecutorExternTask task,
RustAsyncExecutorInternTask data) {
uv_async_t* handle = task;
// store internal task handle to be able to poll it later
handle->data = data;
uv_async_send(handle); // do initial polling (important)
}
void uv_rust_async_executor_init(uv_loop_t *loop) {
// send out executor API to Rust side
rust_async_executor_init(task_new, task_run, task_wake, loop);
}
现在您可以在 libuv 的事件循环中运行您的异步代码,如下所示
int main(void) {
uv_loop_t loop;
uv_loop_init(&loop);
uv_rust_async_executor_init(&loop);
my_async_function(my_async_callback);
uv_run(&loop, UV_RUN_DEFAULT);
uv_loop_close(&loop);
return 0;
}
使用 cbindgen 生成的 C 头文件 rust_async_executor.h。有两种方法可以获取它
- 从本仓库的 include 目录复制
- 通过您自己的 cbindgen 功能生成
在第二种情况下,生成的头文件将位于 target/$PROFILE/include
目录。
内置事件循环驱动程序
为了简化某些广泛使用的事件循环的设置,引入了内置的驱动程序。要使用驱动程序,您应该启用相应的功能。目前支持的以下驱动程序
- uv 内置的 libuv 事件循环集成(见 example_uv)
- dart 内置的 dart-lang 事件循环集成(见 example_dart)
链接问题
Rust 目前存在与从库依赖项重新导出符号相关的问题 (#2771)。
作为临时解决方案,您可以设置构建配置文件如下
[profile.release]
lto = true
incremental = false
与 Tokio 兼容性
此执行器与 tokio 的 futures 不兼容,因为 tokio 仍然有一个与反应器混合的非平凡执行器。
依赖项
~0–1MB