原始问题在这 https://github.com/abersheeran/a2wsgi/issues/7
代码在这 https://github.com/abersheeran/a2wsgi/blob/55ac9c4b82c6988aa4a8280cfc3fadd2565ed37a/a2wsgi/asgi.py
我的思路是实现一对 Event,协程里传数据给 WSGI 线程,然后 WSGI 线程传数据给协程。之前工作的一直还行,直到那个 issue 的用例里,两个协程分别读和写,导致第一个写的消息被覆盖了。
我昨天花了一整个晚上也没想到一个优雅的解决方案。所以发出来请教一下大家,有没有“简洁优雅”的解决方案。
1
SaltCat 2020-12-02 22:34:00 +08:00
感觉你的表述并不清楚: 你没有说是如何从 coroutine send msg 到 thread 进行处理的(try contextvars); 第一个写的消息被覆盖, 是否考虑使用类似 stack 这样的数据结构 + property 防止覆盖? 如果涉及到同 /异步上下文传递, 可以考虑 `contextvars` 这个库: asyncio 在执行协程时会复制一份当前的上下文来执行, 从而避免出现覆写的问题;
希望能解决你的问题. |
2
linw1995 2020-12-03 10:03:07 +08:00
这个 async_event 及 sync_event 每次产生都是一对对的吗?每次 send 或者 receive 生成一个 Event (或者一对)就好了。
|
3
linw1995 2020-12-03 10:18:26 +08:00
仔细看了一遍,题主应该是需要用个 queue 把 sync_event 串行起来吧。这样就不会先处理第二个消息了。
|
4
abersheeran OP |
5
linw1995 2020-12-03 10:52:13 +08:00
|
6
abersheeran OP @linw1995 感谢!看起来可以解决我的问题,我看看他代码怎么做的。
|
7
linw1995 2020-12-03 23:52:11 +08:00
@abersheeran 今天发现了一个和你开发的,功能一样的轮子 https://github.com/django/asgiref
|
8
abersheeran OP @linw1995 兄弟你是在开玩笑嘛…… asgiref 是 ASGI 标准库。里面肯定是有实现 WSGI 到 ASGI 的转换的啊!但是是个参考实现,仅仅是”可用“,速度很差劲,而且会预读 request body,大文件一来它就死了(同理,uvicorn 、starlette 里面自带的也一样)。你可以看看 a2wsgi 项目里提供的 benchmark 。
再告诉你一个秘密,如果你看看 asgiref 贡献者名单,你会发现我也在里面😀zero-copy send 这个拓展标准是我制定的。 |
9
linw1995 2020-12-04 09:47:43 +08:00
@abersheeran 233 我对这方面都不关注的。这个库是在 mitmproxy 源码里发现的,还以为这个普通轮子。原来是根正苗红的官方轮子_(:_」∠)_
|