使用twisted和systemd处理缓存预热

使用twisted和systemd处理缓存预热,twisted,Twisted,我有一个简单的twisted应用程序,我使用systemd服务运行它,执行一个脚本,然后执行一个.tac文件 该应用程序的结构是一个JSON RPC端点(fastjsonrpc),内置在t.w.r.Resource中,该资源位于t.w.s.Site中,服务于t.a.i.TCPServer,整个内容打包到t.a.application中。这个很好用 我遇到的麻烦是在启动时尝试预热缓存。此预热过程非常缓慢(约300秒),会导致systemd超时并终止该过程。增加超时时间并不是一个切实可行的选择,因为

我有一个简单的twisted应用程序,我使用systemd服务运行它,执行一个脚本,然后执行一个.tac文件

该应用程序的结构是一个JSON RPC端点(fastjsonrpc),内置在t.w.r.Resource中,该资源位于t.w.s.Site中,服务于t.a.i.TCPServer,整个内容打包到t.a.application中。这个很好用

我遇到的麻烦是在启动时尝试预热缓存。此预热过程非常缓慢(约300秒),会导致systemd超时并终止该过程。增加超时时间并不是一个切实可行的选择,因为我不希望它阻止系统启动

类似的代码在Apache和wsgi中运行在Flask上的单独堆栈中使用。该服务器会自动启动,并让systemd继续运行,同时它会花时间构建缓存。这种行为对我很好

我尝试在t.w.r.资源的设置函数中使用以下命令调用预热函数:

reactor.callLater(1, ep.warmup, None)
我还没有尝试在systemd中使用它,而是直接在命令行上从twistd中测试它。服务器按预期工作,但不再响应SIGINT(^C)。删除callLater是让服务器响应SIGINT所需的全部

如果直接调用预热功能(而不是通过callLater,即在等待预热完成时使systemd放弃的安排),则生成的服务器也会继续响应SIGINT

  • 有没有更好的方法来处理这种长时间运行的预热代码
  • 为什么twistd/反应堆对SIGINT没有反应?我是不是遗漏了什么

  • Twisted是一个单线程的东西。听起来好像你的“缓存预热”代码在那300秒内阻塞了反应堆。解决这个问题的一个简单方法是使用
    deferToThread
    让它在不阻塞反应器的情况下运行。

    Twisted是单线程的。听起来好像你的“缓存预热”代码在那300秒内阻塞了反应堆。解决这个问题的一个简单方法是使用
    deferToThread
    ,让它在不阻塞反应器的情况下运行。

    我对它阻塞反应器300秒没有问题,但我需要反应器在那之后正常响应。否则,反应堆正常工作,但不再响应SIGINT/SIGTERM,需要停止SIGKILL。deferToThread对我来说不太可能工作得很好,因为我的缓存是由python对象组成的非常复杂的网络。或者,您可以重新编写“warmup”例程,以返回延迟的线程,从而定期将控制权交给反应器。我不确定这是否/如何与您看到的信号行为相关。。但这是一个更好的方法。一种方法是只使用@inlineCallbacks并每隔这么多次循环(如果它是一个循环)进行一次“屈服”。我对它在300秒内阻塞反应器没有问题,但我需要反应器在那之后正常响应。否则,反应堆正常工作,但不再响应SIGINT/SIGTERM,需要停止SIGKILL。deferToThread对我来说不太可能工作得很好,因为我的缓存是由python对象组成的非常复杂的网络。或者,您可以重新编写“warmup”例程,以返回延迟的线程,从而定期将控制权交给反应器。我不确定这是否/如何与您看到的信号行为相关。。但这是一个更好的方法。一种方法是只使用@inlineCallbacks,并每隔这么多次循环迭代“产生”(如果是循环)。