• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

allura


Commit MetaInfo

修訂4a3e4835d96aeb1f2fd8d8478f1e4ec3b6db8baf (tree)
時間2010-04-24 06:01:55
作者Rick Copeland <rcopeland@geek...>
CommiterRick Copeland

Log Message

[#266] - Make reactor processes auto-restart on unhandled exceptions

This commit includes

- The RestartableProcess multiprocessing.Process proxy which has .check() and .reinit() to allow processes to be restarted
- Updates so that the reactor process uses RestartableProcess and monitors its child processes

Change Summary

差異

--- a/pyforge/pyforge/command/reactor.py
+++ b/pyforge/pyforge/command/reactor.py
@@ -10,6 +10,25 @@ from carrot.messaging import Consumer, ConsumerSet
1010
1111 from . import base
1212
13+class RestartableProcess(object):
14+
15+ def __init__(self, log, *args, **kwargs):
16+ self._log = log
17+ self._args, self._kwargs = args, kwargs
18+ self.reinit()
19+
20+ def reinit(self):
21+ self._process = Process(*self._args, **self._kwargs)
22+
23+ def check(self):
24+ if not self.is_alive():
25+ self._log.error('Process %d has died, restarting', self.pid)
26+ self.reinit()
27+ self.start()
28+
29+ def __getattr__(self, name):
30+ return getattr(self._process, name)
31+
1332 class ReactorSetupCommand(base.Command):
1433
1534 summary = 'Configure the RabbitMQ queues and bindings for the given set of plugins'
@@ -63,14 +82,14 @@ class ReactorCommand(base.Command):
6382
6483 def command(self):
6584 self.basic_setup()
66- processes = [ Process(target=self.periodic_main, args=()) ]
85+ processes = [ RestartableProcess(target=self.periodic_main, args=()) ]
6786 configs = [
6887 dict(plugin_name=name,
6988 method=method, xn=xn, qn=qn, keys=keys)
7089 for name, plugin in self.plugins
7190 for method, xn, qn, keys in plugin_consumers(name, plugin) ]
7291 for x in xrange(self.options.proc):
73- processes.append(Process(target=self.multi_worker_main,
92+ processes.append(RestartableProcess(target=self.multi_worker_main,
7493 args=(configs,)))
7594 continue
7695 if self.options.dry_run: return configs
@@ -82,7 +101,9 @@ class ReactorCommand(base.Command):
82101 for p in processes:
83102 p.start()
84103 while True:
85- time.sleep(300)
104+ for x in xrange(60):
105+ time.sleep(5)
106+ for p in processes: p.check()
86107 base.log.info('=== Mark ===')
87108
88109 def multi_worker_main(self, configs):
@@ -98,6 +119,7 @@ class ReactorCommand(base.Command):
98119 cset.add_consumer(c)
99120 if self.options.dry_run: return
100121 else: # pragma no cover
122+ base.log.info('Ready to handle messages')
101123 for x in cset.iterconsume():
102124 pass
103125
@@ -252,5 +274,3 @@ def debug(): # pragma no cover
252274 p.setup(sys._getframe(), None)
253275 p.cmdloop()
254276 p.forget()
255-
256-