Ñò »ÏâIc @sdZddkZddkZyeWn#ej oddklZnXddkZddkZddk Z ddk Z ddk Z de fd„ƒYZeƒZeiƒe_eiƒe_eiƒe_eiƒe_eiƒe_de fd„ƒYZeƒZdS(s An implementation of the Web Site Process Bus. This module is completely standalone, depending only on the stdlib. Web Site Process Bus -------------------- A Bus object is used to contain and manage site-wide behavior: daemonization, HTTP server start/stop, process reload, signal handling, drop privileges, PID file management, logging for all of these, and many more. In addition, a Bus object provides a place for each web framework to register code that runs in response to site-wide events (like process start and stop), or which controls or otherwise interacts with the site-wide components mentioned above. For example, a framework which uses file-based templates would add known template filenames to an autoreload component. Ideally, a Bus object will be flexible enough to be useful in a variety of invocation scenarios: 1. The deployer starts a site from the command line via a framework- neutral deployment script; applications from multiple frameworks are mixed in a single site. Command-line arguments and configuration files are used to define site-wide components such as the HTTP server, WSGI component graph, autoreload behavior, signal handling, etc. 2. The deployer starts a site via some other process, such as Apache; applications from multiple frameworks are mixed in a single site. Autoreload and signal handling (from Python at least) are disabled. 3. The deployer starts a site via a framework-specific mechanism; for example, when running tests, exploring tutorials, or deploying single applications from a single framework. The framework controls which site-wide components are enabled as it sees fit. The Bus object in this package uses topic-based publish-subscribe messaging to accomplish all this. A few topic channels are built in ('start', 'stop', 'exit', and 'graceful'). Frameworks and site containers are free to define their own. If a message is sent to a channel that has not been defined or has no listeners, there is no effect. In general, there should only ever be a single Bus object per process. Frameworks and site containers share a single Bus object by publishing messages and subscribing listeners. The Bus object works as a finite state machine which models the current state of the process. Bus methods move it from one state to another; those methods then publish to subscribed listeners on the channel for the new state. O | V STOPPING --> STOPPED --> EXITING -> X A A | | \___ | | \ | | V V STARTED <-- STARTING iÿÿÿÿN(tSett _StateEnumcBs'eZdefd„ƒYZd„ZRS(tStatecBseZdZd„ZRS(cCs d|iS(Ns states.%s(tname(tself((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyt__repr__PsN(t__name__t __module__tNoneRR(((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyRNscCs7t||iƒo ||_nti|||ƒdS(N(t isinstanceRRtobjectt __setattr__(Rtkeytvalue((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyR Ss (RRR RR (((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyRMstBuscBsÂeZdZeZeiZeZd„Zdd„Z d„Z d„Z d„Z d„Zd„Zd„Zd „Zd d „Zd d „Zd „Zd„Zddd„Zdded„ZRS(swProcess state-machine and messenger for HTTP site deployment. All listeners for a given channel are guaranteed to be called even if others at the same channel fail. Each failure is logged, but execution proceeds on to the next listener. The only way to stop all processing from inside a listener is to raise SystemExit and stop the whole server. cCsUt|_ti|_tg}dD]}||tƒfq#~ƒ|_h|_dS(Ntstarttstoptexittgracefultlog(sstartsstopsexitsgracefulslog( tFalsetexecvtstatestSTOPPEDtstatetdicttsett listenerst _priorities(Rt_[1]tchannel((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyt__init__ms   )cCsr||ijotƒ|i|RtSTARTINGRRR9tSTARTEDR,R-R1R/R0R(Rte_info((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyR±s$       cCs\yA|iƒti|_|idƒ|idƒ|idƒWntidƒnXdS(s2Stop all services and prepare to exit the process.s Bus EXITINGRs Bus EXITEDiFN(RRR:RRR9tost_exit(R((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyRÈs    cCst|_|iƒdS(sÒRestart the process (may close connections). This method does not restart the process from the calling thread; instead, it stops the bus and asks the main thread to call execv. N(R1RR(R((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pytrestartÚs cCs|idƒ|idƒdS(sAdvise all services to reload.s Bus gracefulRN(RR9(R((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyRãs gš™™™™™¹?cCsy|itid|ƒWn\ttfj o|idƒ|iƒn.tj o!|idƒ|iƒ‚nX|idƒxyti ƒD]k}|ti ƒjoR|i ƒoEt ti dƒo |i}n |iƒ}|p|iƒqþq“q“W|io|iƒndS(sÂWait for the EXITING state, KeyboardInterrupt or SystemExit. This function is intended to be called only by the main thread. After waiting for the EXITING state, it also waits for all threads to terminate, and then calls os.execv if self.execv is True. This design allows another thread to call bus.restart, yet have the main thread perform the actual execv call (required on some platforms). tintervals%Keyboard Interrupt: shutting down buss$SystemExit raised: shutting down buss)Waiting for child threads to terminate...tdaemonN(twaitRR:R,tIOErrorRRR-t threadingt enumeratet currentThreadtisAlivethasattrtThreadRHtisDaemontjoinRt _do_execv(RRGtttd((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pytblockès(          cs}t|ttfƒo |‰n |g‰‡‡‡fd†}ytidi|ƒWnttfj onX|ƒdS(sWait for the given state(s).cs)x"ˆiˆjotiˆƒqWdS(N(Rttimetsleep((RRRG(s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyt_waitstpsycoN(R ttupletlistR/tmodulest cannotcompiletKeyErrortAttributeError(RRRGRY((RRGRs=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyRIs   cCs‡ti}|iddi|ƒƒ|idtiƒtidjo)g}|D]}|d|qR~}ntiti|ƒdS(sÈRe-execute the current process. This must be called from the main thread, because certain platforms (OS X) don't allow execv to be called in a child thread very well. sRe-spawning %st itwin32s"%s"N( R/targvRRRtinsertt executabletplatformRDR(RR2Rtarg((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyRS)s  )cCsCti|_|idƒ|idƒti|_|idƒdS(sStop all services.s Bus STOPPINGRs Bus STOPPEDN(RtSTOPPINGRRR9R(R((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyR7s     cs—|djo d}n|djo h}n|f|}‡fd†}tid|d|d|ƒ}|id|iƒƒ|iƒˆiƒ|S(s?Start 'func' in a new thread T, then start self (and return T).cs!ˆitiƒ|||ŽdS(N(RIRRB(tfunctatkw(R(s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyt _callbackGsttargetR2R3s Bus Callback N((RRKRPtsetNametgetNameR(RRiR2R3RlRT((Rs=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pytstart_with_callback?s       ticCsN|o0tiƒ}|dditi|Œƒ7}n|id||ƒdS(s>Log the given message. Append the last traceback if requested.s RqRN(R/R0RRt _tracebacktformat_exceptionR9(RtmsgR(R)R4((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyRRs $N(RRt__doc__RRRRRRRR$R'R9R>RRRFRRVRIRSRRpR(((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyR_s&    !    )   (RuR?RDRt NameErrortsetsRR/RKRWR)RrR;R RRRRRARBRhR:Rtbus(((s=/usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.pyt=s(        ú