uWSGI Mule

Mule是活在uWSGI栈中的worker进程,但通过socket连接是不能访问的,它可以作为一种通用子系统使用,以卸载任务。你可以将它们看成一个比较原始的 spooler

它们可以访问整个 uWSGI API,可以管理信号,并且可以通过一个简单的基于字符串的消息系统来进行通信。

要启动一个mule (你可以启动无限个它们),需要多少次,就使用多少次 mule 选项。

Mule有两种模式,

  • 纯信号模式(默认模式)。在这种模式下,mule像正常的worker那样加载你的应用。它们只能响应 uWSGI signals
  • 编程模式。在这种模式下,mule与你的应用分开加载一个程序。见 ProgrammedMules.

默认情况下,每个mule以纯信号模式启动。

uwsgi --socket :3031 --mule --mule --mule --mule
<uwsgi>
    <socket>:3031</socket>
    <mule/>
    <mule/>
    <mule/>
    <mule/>
</uwsgi>

基本使用

import uwsgi
from uwsgidecorators import timer, signal, filemon

# run a timer in the first available mule
@timer(30, target='mule')
def hello(signum):
    print "Hi! I am responding to signal %d, running on mule %d" % (signum, uwsgi.mule_id())

# map signal 17 to mule 2
@signal(17, target='mule2')
def i_am_mule2(signum):
    print "Greetings! I am running in mule number two."

# monitor /tmp and arouse all of the mules on modifications
@filemon('/tmp', target='mules')
def tmp_modified(signum):
    print "/tmp has been modified. I am mule %d!" % uwsgi.mule_id()

赋予mule智慧

如前所述,可以对mule进行编程。要赋予一个mule自定义逻辑,则将脚本名传递给 mule 选项。

uwsgi --socket :3031 --mule=somaro.py --mule --mule --mule

这将会运行4个mule,3个处于纯信号模式,一个运行 somaro.py

# somaro.py
from threading import Thread
import time

def loop1():
    while True:
        print "loop1: Waiting for messages... yawn."
        message = uwsgi.mule_get_msg()
        print message

def loop2():
    print "Hi! I am loop2."
    while True:
        time.sleep(2)
        print "This is a thread!"

t = Thread(target=loop2)
t.daemon = True
t.start()

if __name__ == '__main__':
    loop1()

因此,正如你可以从这个例子看到的那样,你可以在一个编程mule中使用 mule_get_msg() 来接收消息。相同编程mule中的多个线程会等待消息。

如果你想阻塞一个mule,以等待一个uWSGI信号,而不是消息,那么你可以使用 uwsgi.signal_wait()

使用 uwsgi.mule_msg() 来发送一个消息给编程mule。可以从uWSGI栈中的任何一个地方发送mule消息,包括但不限制于worker, spooler, 另一个mule。

# Send the string "ciuchino" to mule1.
# If you do not specify a mule ID, the message will be processed by the first available programmed mule.
uwsgi.mule_msg("ciuchino", 1)

由于你可以生成无限个mule,因此你或许需要某些形式的同步 —— 例如,如果你正在开发一个任务管理子系统,并且不希望两个mule能够同时启动相同的任务。你很幸运 —— 见