multithreading - How to (repeatedly) create and shut down multiple instances of python twisted factory / reactor? -


firstly, apologies title thread - worded better, i'm not sure know how! anyway...

i have following methods start, , stop smtp server respectively:

    # -----------------------------------------------------------------------  def startserver(configname = 'default'):     try:         svrcfg = getserverconfig(configname)         startlogger (svrcfg.find('logfile').text)         portal = portal(simplerealm())         checker = inmemoryusernamepassworddatabasedontuse()         checker.adduser("guest", "password")         portal.registerchecker(checker)         serverport = int(svrcfg.find('port').text)         reactor.listentcp(serverport, consolesmtpfactory((portal, svrcfg)))         thread(target=reactor.run, args=(false,)).start()         # reactor.run()     except twisted.internet.error.cannotlistenerror, e:         errstring = "cannot start server, port " + svrcfg.find('port').text + " busy"         log.msg (errstring, loglevel=logging.critical)     except:         log.msg ("unknown error", loglevel=logging.critical)  # -----------------------------------------------------------------------  def stopserver():     reactor.callfromthread(reactor.stop)  # ----------------------------------------------------------------------- 

the long term plan startserver , stopserver robotframework keywords. though, of course sufficient go python command line, import source module (mailserver.py) , "mailserver.startserver()" or "mailserver.stopserver()" etc. fine starting server first time, , stopping it.

however want able start / stop multiple, concurrent mailservers, listening on different ports - example, mailserver.startserver("p25") mailserver.startserver("p26"), mailserver.stopserver("p25") start 2 instances, shut first 1 down.

even existing code, restarting "default" listener fails reactornotrestartable error... , of course, starting "default" listener, starting "p26" listener results in "reactoralreadyrunning" error.

can offer advice on how around these errors? firstly, how multiple listeners, , secondly, how specify 1 shut down part of "stopserver"?

(incidentally, using thread allow startserver exit next robotframework keyword execute...)

many thanks

edit - following @jeanpaul-calderone 's answer... i've managed create following:

so i've tweaked code support adding / removing listeners, below:

def addlistener(configname = 'default'):     try:         svrcfg = getserverconfig(configname)         startlogger (svrcfg.find('logfile').text)         portal = portal(simplerealm())         checker = inmemoryusernamepassworddatabasedontuse()         checker.adduser("guest", "password")         portal.registerchecker(checker)         serverport = int(svrcfg.find('port').text)         listenerport = reactor.listentcp(serverport, consolesmtpfactory((portal, svrcfg)))         runninglisteners[configname] = listenerport         print runninglisteners     except twisted.internet.error.cannotlistenerror, e:         errstring = "cannot start server, port " + svrcfg.find('port').text + " busy"         log.msg (errstring, loglevel=logging.critical)     except:         log.msg ("unknown error", loglevel=logging.critical)  # -----------------------------------------------------------------------  def stoplistener(configname = 'default'):     listenerport = runninglisteners[configname]     print listenerport     listenerport.stoplistening()     listenerport.connectionlost("closing listener requested")     del runninglisteners[configname]   # -----------------------------------------------------------------------  thread(target=reactor.run, args=(false,)).start() runninglisteners={} 

i can add , remove multiple listeners... however, when tried (for debug purposes) ctrl-d python command line session, hung - had ctrl-z, , kill job.

so realised reactor had been left running, added:

def stopreactor():     reactor.callfromthread(reactor.stop) 

but when ctrl-d python session:

    unhandled error in deferred: unhandled error traceback (most recent call last):   file "/usr/local/lib/python2.7/site-packages/twisted/internet/base.py", line 1201, in mainloop     self.rununtilcurrent()   file "/usr/local/lib/python2.7/site-packages/twisted/internet/base.py", line 824, in rununtilcurrent     call.func(*call.args, **call.kw)   file "/usr/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 382, in callback     self._startruncallbacks(result)   file "/usr/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 490, in _startruncallbacks     self._runcallbacks() --- <exception caught here> ---   file "/usr/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 577, in _runcallbacks     current.result = callback(current.result, *args, **kw)   file "/usr/local/lib/python2.7/site-packages/twisted/internet/task.py", line 832, in <lambda>     d.addcallback(lambda ignored: callable(*args, **kw))   file "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 1115, in connectionlost     self._closesocket(true)   file "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 123, in _closesocket     skt = self.socket exceptions.attributeerror: 'port' object has no attribute 'socket' 

can advise getting wrong?

you can start twisted reactor once. if have multiple tasks want accomplish, need start reactor before first 1 , stop after last one. can't start , stop around each task.

you may find crochet helpful in managing reactor usage pattern.


Comments

Popular posts from this blog

java - Oracle EBS .ClassNotFoundException: oracle.apps.fnd.formsClient.FormsLauncher.class ERROR -

c# - how to use buttonedit in devexpress gridcontrol -

nvd3.js - angularjs-nvd3-directives setting color in legend as well as in chart elements -