我已经为uWSGI编写了一个简单的插件。
#include <uwsgi.h>
static void cycle() {
uwsgi_log("In master cycle\n");
}
struct uwsgi_plugin master_plugin = {
.name = "master",
.master_cycle = cycle,
};
现在我想在初始化WSGI应用程序的同一个python解释器中调用主循环线程中的一些python代码有uWSGI的API吗我可以使用python插件:https://github.com/unbit/uwsgi/blob/master/plugins/python/python_plugin.c如果可能的话,请给我一小段怎么做。
更新
来自评论的一些上下文
我想实现内存缓存,利用写时拷贝特性,所以我将数据加载到主进程并重新标记工作人员,然后他们都得到新的数据。
我不能使用uWSGI缓存,因为序列化/反序列化大约需要200毫秒,而且我缓存的对象是复杂的python对象,例如SQLAlchemy模型实例,实际上是此类实例的列表用协议2腌制的样本列表占用大约6Mb的空间。
我想保持缓存和缓存装饰器一样简单,所以缓存的方法不关心被缓存这是为了向后兼容和以后添加缓存方法的简单性。
我不能同时用uwsgi.reload()重新加载所有工作线程,原因太多:1)重新定位所有工作线程(20-30个进程)可能会对每个时段的性能产生影响-相反,我希望重新定位及时分发的工作线程(例如每5秒)2)可能有多个缓存具有不同的过期周期完全重新加载将使它们在一次给数据库不必要的加载
最初,我在主进程中创建了一个新线程,该线程周期性地重新验证缓存,并将HUP信号发送给工作人员以进行优雅的重新工作问题是,当worker实际死亡和重生时,没有完全的控制权,所以当我的线程在缓存更新和分叉的worker中得到损坏的数据时,它可能分叉有没有一种方法可以在不进行线程同步的情况下提供一致的数据
为了解决上面的问题,我希望主循环中的一些代码能够通过更新线程检查一些信号量,并在缓存更新结束之前挂起主循环这将保证在缓存更新期间没有fork
最佳答案
在阅读了您的需求之后,我认为您最好的选择是uWSGI 2.1 fork服务器功能:
https://github.com/unbit/uwsgi-docs/blob/master/ForkServer.rst
这展示了如何将其与python一起使用(该功能最初仅为perl开发):
https://github.com/unbit/uwsgi-docs/blob/master/examples/CPythonForkServer.rst
这条线包含了一些关于它的注释
http://lists.unbit.it/pipermail/uwsgi/2014-June/007444.html
基本上,您有两个“不相关”的实例,一个是您不断构建缓存的实例,另一个是您需要时从该实例派生出来的实例。
最后,如果您真的想在主循环中运行自定义python代码,可以从以下代码片段开始:
#include <uwsgi.h>
void PyRun_SimpleString(char *);
static void cycle() {
uwsgi_log("In master cycle\n");
PyRun_SimpleString("print \"aaa\"");
}
struct uwsgi_plugin master_plugin = {
.name = "master",
.master_cycle = cycle,
};