uWSGI Mule

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

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

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

Mule有两种模式,

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

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

  1. uwsgi --socket :3031 --mule --mule --mule --mule
  1. <uwsgi>
  2. <socket>:3031</socket>
  3. <mule/>
  4. <mule/>
  5. <mule/>
  6. <mule/>
  7. </uwsgi>

基本使用

  1. import uwsgi
  2. from uwsgidecorators import timer, signal, filemon
  3.  
  4. # run a timer in the first available mule
  5. @timer(30, target='mule')
  6. def hello(signum):
  7. print "Hi! I am responding to signal %d, running on mule %d" % (signum, uwsgi.mule_id())
  8.  
  9. # map signal 17 to mule 2
  10. @signal(17, target='mule2')
  11. def i_am_mule2(signum):
  12. print "Greetings! I am running in mule number two."
  13.  
  14. # monitor /tmp and arouse all of the mules on modifications
  15. @filemon('/tmp', target='mules')
  16. def tmp_modified(signum):
  17. print "/tmp has been modified. I am mule %d!" % uwsgi.mule_id()

赋予mule智慧

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

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

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

  1. # somaro.py
  2. from threading import Thread
  3. import time
  4.  
  5. def loop1():
  6. while True:
  7. print "loop1: Waiting for messages... yawn."
  8. message = uwsgi.mule_get_msg()
  9. print message
  10.  
  11. def loop2():
  12. print "Hi! I am loop2."
  13. while True:
  14. time.sleep(2)
  15. print "This is a thread!"
  16.  
  17. t = Thread(target=loop2)
  18. t.daemon = True
  19. t.start()
  20.  
  21. if __name__ == '__main__':
  22. loop1()

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

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

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

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

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