安全等待另一个进程中的功能

时间:2017-07-25 19:55:06

标签: c++11 multiprocessing gunicorn python-asyncio locust

TL; DR

如何在单独的进程中安全地await执行函数(在strint作为参数并且不需要任何其他上下文)?

长篇故事

我有aiohtto.web网络API使用Boost.Python包装进行C++扩展,在gunicorn下运行(我打算在Heroku上部署它),由{{进行测试1}}。

关于扩展:它只有一个执行非阻塞操作的函数 - 接受一个字符串(和一个整数用于超时管理),用它进行一些计算并返回一个新字符串。对于每个输入字符串,它只是一个可能的输出(超时除外,但在这种情况下,必须引发locust异常并由Boost.Python转换为与Python兼容的异常。)

简而言之,特定URL的处理程序执行以下代码:

C++

其中res = await loop.run_in_executor(executor, func, *args) executor实例,ProcessPoolExecutor -function来自C ++扩展模块。 (在实际项目中,此代码位于类的coroutine方法中,func - 它func仅执行classmethod函数并返回结果)

捕获错误

当新请求到达时,我会通过C++提取它的POST数据,然后将其存储到名为request.post()的自定义类的实例中(因为我有不知道如何以另一种方式命名它)。因此Call对象包含请求附带的所有输入数据(字符串),请求接收时间和唯一call

然后它进入名为id的类(不是Handler请求处理程序),将其传递给另一个类'内部有aiohttp的方法。但loop.run_in_executor有一个像中间件一样工作的日志系统 - 读取每个传入的Handler对象的id和接收时间,并使用一条消息记录它,告诉你它刚开始执行,成功执行或获取麻烦。此外,call具有Handler并将所有错误存储在try/except对象中,以便日志记录中间件知道发生了什么错误,或者返回了哪个输出扩展

测试

我有单元测试,只用这个代码创建256个协同程序,执行程序有256个工作程序,它运行良好。

但是当使用Locust进行测试时出现问题。我使用了4名Gunicorn工人和4名遗嘱执行人员进行这种测试。在某些时候应用程序刚开始返回错误的输出。

我的Locust的call被配置为使用所有可用信息记录每个故障响应:输出字符串,错误字符串,输入字符串(由应用程序返回),id。所有模拟请求都是相同的,但TaskSet对每个模拟请求都是唯一的。

将Gunicorn的id选项设置为max_requests请求时,情况会更好,但失败仍然存在。

有趣的是,有时我会触发"错误的输出"只需停止并启动Locust的测试就可以了。

我需要100%保证我的网络API能够正常运行。

更新&溶液

刚刚让我的队友回顾C ++代码 - 问题出在全局变量中。在某种程度上,对于256个并行协程来说,这不是一个问题,但是对于Gunicorn而言。

0 个答案:

没有答案