3个版本
0.0.3 | 2022年10月10日 |
---|---|
0.0.2 | 2022年10月4日 |
0.0.1 | 2022年8月26日 |
#1396 在 HTTP服务器
32KB
543 行
Parviocula
一个简单的ASGI服务器,旨在帮助从Python ASGI应用程序过渡到Axum应用程序(或者未来,任何基于Tower的Web框架)。
目标是允许在Rust中编写基于Axum的应用程序,同时可以选择将尚未在Rust中实现的请求处理权退回到Python ASGI应用程序,从而允许从基于ASGI的Python服务逐步过渡到基于Axum的Rust服务,而无需一次完成。
这承担了你目前使用的ASGI服务器的角色,使用Hyper处理所有HTTP协议相关事宜,并通过pyo3将请求转换为ASGI消息,然后将它们传递给Python ASGI应用程序。
这需要编写一个小的基于pyo3的包装器,以便从Python启动Rust服务器。请参见asgi_only示例,以获取一个最小的起始示例。在示例中的README.md
中详细说明了项目的配置。
限制
虽然大多数情况下您可以直接在Axum路由器上使用fallback
将尚未在Rust中实现的内容转发到Python代码,但如果在相同路径上有一些同时在Rust和Python中实现的方法(例如,由Rust处理的GET请求,以及由Python处理的POST请求),则需要明确告诉路由器将Python方法转发到ASGI路由器。请参见mixed_routes示例。
从嵌套的Axum路由器转发路由到ASGI应用将丢失父路由器的路径信息,因此ASGI应用只能接收到当前路由器的路径信息。目前建议仅使用单个扁平路由器,并在替换所有ASGI组件后再考虑拆分路由器。
常见问题解答
它非常快吗?
🤷. 使用 oha 在我的机器上测试,与 uvicorn 进行比较,使用 asgi_example
,使用 maturin develop --release
构建,使用 oha http://localhost:3000/echo -z 10s -c 1 -H "user-agent: oha" -d "hello"
运行,目前仅达到uvicorn单个工作进程每秒请求量的 ~80-90%。但是使用50个工作进程(oha ... -c 50
),可以达到uvicorn每秒请求量的 ~200%。当用这个替换我在大型集成测试套件中使用的uvicorn时,我发现测试套件的完成速度没有显著差异。
它支持哪些ASGI应用程序框架?
我直接使用了 Starlette 和 FastAPI。我怀疑其他框架也可能工作,但我还没有测试过。
我能用这个替换我的Python ASGI服务器吗?
可能吧?但除非你用它来过渡你的代码库到Rust,否则不值得。它可能更慢(至少如果你像我一样使用uvicorn),你可能会失去当前成熟的ASGI服务器提供的许多优点。
《ServerContext》API太糟糕了!你能改变它吗?
请随时提出建议或提交更改的拉取请求,我会考虑。
你做错了X,它应该这样...!
再次提醒,请随时提出建议或提交更改的拉取请求,我会查看更改。
待办事项
- 让它更快?
- 为ASGI服务器编写一些测试,以确保其符合规范。
- 将其实现为Tower服务,而不是Axum处理器
- 弄清楚
ServerContext::start
函数是否可以await
直至服务器实际上开始监听请求 - 从Rust启动服务器。即作为应用程序启动的入口点更容易替换Python ASGI服务器。(这由于直接链接到Python而变得很复杂,我从Rust启动asyncio事件循环时遇到了麻烦。最终,从Python启动要容易得多,而且我认为从Rust启动实际上也没有什么好处。)
- pyo3_asyncio有时会由于使用
call_soon_threadsafe
在其futures上调用set_result
而生成InvalidStateError
,在某些情况下(我还没有能够为它们创建最小示例),在call_soon_threadsafe
调用后,但在实际执行set_result
调用之前,futures正在被取消。这不会影响任何事情(因为futures被取消了),但看到日志中的错误很烦人。 - Python类型辅助工具
- 更多的跟踪支持?
- WebSocket?
- 弄清楚OpenAPI的故事
依赖关系
~11–20MB
~278K SLoC