从uWSGI主循环调用python代码

时间:2014-10-28 16:53:44

标签: python c uwsgi

我为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吗?如果可能的话,请给我一个片段如何做。

更新

评论的一些背景

  1. 我想实现利用写时复制功能的内存缓存,因此我将数据加载到主进程并重新编写工作者,然后他们都获得了新数据。
  2. 我不能使用uWSGI缓存,因为序列化/反序列化需要大约200ms,而我缓存的对象是复杂的python对象,例如SQLAlchemy模型实例,实际上是这样的实例的列表。使用协议2进行腌制的样本列表大约需要6Mb空间。
  3. 我希望缓存像缓存装饰器一样简单,因此缓存的方法不关心缓存。这是为了向后兼容,以及将来添加缓存方法的简单性。
  4. 我无法一次性使用uwsgi.reload()重新加载所有工作人员的原因:1)重新执行所有工作人员(20-30个流程)可能会导致每个时期的性能影响 - 相反,我想重新分配工作人员时间(比如说每5秒)2)可能有几个缓存具有不同的到期时间,完全重新加载会立即使它们全部无效并为数据库提供不必要的负载
  5. 最初,我在主进程中创建了一个新线程,它定期重新验证缓存并向工作人员发送HUP信号以进行正常的重新编译。问题是当工作人员实际死亡和重生时没有完全控制,所以当我在缓存更新和分叉工作程序中的线程获得损坏的数据时它可能会分叉。有没有一种方法可以在没有线程同步的情况下提供一致的数据
  6. 为了解决上面的问题,我想在主循环中使用一些代码来检查一些信号量,更新线程并暂停主循环,直到缓存更新结束。这将保证在缓存更新期间没有分叉

1 个答案:

答案 0 :(得分:1)

在阅读完您的要求之后,我认为您最好的选择是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

基本上你有两个&#34;无关&#34;实例,一个用于不断构建缓存的实例,另一个用于在需要时从该缓存分叉的实例。

最后,如果你真的想在主循环中运行自定义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,
};