Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1627

Show
Ignore:
Timestamp:
03/05/07 15:22:13
Author:
fumanchu
Message:

New pywebd module. Trunk is now "3.1alpha".

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/__init__.py

    r1622 r1627  
    5858""" 
    5959 
    60 __version__ = "3.0.1
     60__version__ = "3.1alpha
    6161 
    6262from urlparse import urljoin as _urljoin 
     
    7777        popped from the class dict and folded into the class docstring. 
    7878         
    79         The naming convention for attribute docstrings is: <attrname> + "__doc". 
     79        The naming convention for attribute docstrings is: 
     80            <attrname> + "__doc". 
    8081        For example: 
    8182         
     
    158159 
    159160from cherrypy import _cpdispatch as dispatch 
    160 from cherrypy import _cprequest 
    161 from cherrypy.lib import http as _http 
    162 from cherrypy import _cpengine 
    163 engine = _cpengine.Engine() 
    164161 
    165162from cherrypy import _cptools 
    166163tools = _cptools.default_toolbox 
    167164Tool = _cptools.Tool 
     165 
     166from cherrypy import _cprequest 
     167from cherrypy.lib import http as _http 
    168168 
    169169from cherrypy import _cptree 
     
    174174server = _cpserver.Server() 
    175175 
     176from cherrypy import pywebd 
     177engine = pywebd.engine 
     178 
     179# Timeout monitor 
     180class _TimeoutMonitor(pywebd.plugins.Monitor): 
     181     
     182    def __init__(self, engine, channel=None): 
     183        self.servings = [] 
     184        pywebd.plugins.Monitor.__init__(self, engine, self.run, channel) 
     185     
     186    def acquire(self): 
     187        self.servings.append((serving.request, serving.response)) 
     188     
     189    def release(self): 
     190        try: 
     191            self.servings.remove((serving.request, serving.response)) 
     192        except ValueError: 
     193            pass 
     194     
     195    def run(self): 
     196        """Check timeout on all responses. (Internal)""" 
     197        for req, resp in self.servings: 
     198            resp.check_timeout() 
     199_timeout_monitor = _TimeoutMonitor(engine, "CherryPy Timeout Monitor") 
     200 
     201# Add an autoreloader (the 'engine' config namespace may detach/attach it). 
     202engine.autoreload = pywebd.plugins.Autoreloader(engine) 
     203pywebd.plugins.Reexec(engine) 
     204_thread_manager = pywebd.plugins.ThreadManager(engine) 
     205 
     206 
    176207def quickstart(root, script_name="", config=None): 
    177     """Mount the given root, start the engine and builtin server, then block.""" 
     208    """Mount the given root, start the builtin server (and engine), then block.""" 
    178209    if config: 
    179210        _global_conf_alias.update(config) 
    180211    tree.mount(root, script_name, config) 
    181     server.quickstart() 
     212     
     213    engine.subscribe('start', server.quickstart) 
     214     
     215    s = pywebd.plugins.SignalHandler(engine) 
     216    s.set_handler('SIGTERM', engine.stop) 
     217    s.set_handler('SIGHUP', engine.restart) 
     218     
    182219    engine.start() 
     220    engine.block() 
    183221 
    184222 
     
    324362# Using an access file makes CP about 10% slower. Leave off by default. 
    325363log.access_file = '' 
    326  
     364engine.log = lambda msg, traceback=False: log.error(msg, 'ENGINE', 
     365                                                    traceback=traceback) 
    327366 
    328367#                       Helper functions for CP apps                       # 
     
    454493from cherrypy import _cpchecker 
    455494checker = _cpchecker.Checker() 
     495engine.subscribe('start', checker) 
  • trunk/cherrypy/_cpchecker.py

    r1575 r1627  
    143143    extra_config_namespaces = [] 
    144144     
    145     def _known_ns(self, config): 
     145    def _known_ns(self, app): 
    146146        ns = ["wsgi"] 
    147         ns.extend(cherrypy.engine.request_class.namespaces.keys()) 
     147        ns.extend(app.toolboxes.keys()) 
     148        ns.extend(app.request_class.namespaces.keys()) 
    148149        ns.extend(cherrypy.config.namespaces.keys()) 
    149150        ns += self.extra_config_namespaces 
    150151         
    151         for section, conf in config.iteritems(): 
     152        for section, conf in app.config.iteritems(): 
    152153            is_path_section = section.startswith("/") 
    153154            if is_path_section and isinstance(conf, dict): 
     
    169170        """Process config and warn on each unknown config namespace.""" 
    170171        for sn, app in cherrypy.tree.apps.iteritems(): 
    171             self._known_ns(app.config
     172            self._known_ns(app
    172173     
    173174     
  • trunk/cherrypy/_cpconfig.py

    r1612 r1627  
    8787You can define your own namespaces to be called at the Global, Application, 
    8888or Request level, by adding a named handler to cherrypy.config.namespaces, 
    89 app.namespaces, or cherrypy.engine.request_class.namespaces. The name can 
     89app.namespaces, or app.request_class.namespaces. The name can 
    9090be any string, and the handler must be either a callable or a (Python 2.5 
    9191style) context manager. 
     
    144144     
    145145    If the given config is a filename, it will be appended to 
    146     cherrypy.engine.reload_files and monitored for changes. 
     146    the list of files to monitor for "autoreload" changes. 
    147147    """ 
    148148    if isinstance(other, basestring): 
    149         if other not in cherrypy.engine.reload_files: 
    150             cherrypy.engine.reload_files.append(other) 
     149        cherrypy.engine.publish('Autoreloader', 'add()', other) 
    151150     
    152151    # Load other into base 
     
    240239    namespaces = NamespaceSet( 
    241240        **{"server": lambda k, v: setattr(cherrypy.server, k, v), 
    242            "engine": lambda k, v: setattr(cherrypy.engine, k, v), 
    243241           "log": lambda k, v: setattr(cherrypy.log, k, v), 
    244242           "checker": lambda k, v: setattr(cherrypy.checker, k, v), 
     
    257255        if isinstance(config, basestring): 
    258256            # Filename 
    259             if config not in cherrypy.engine.reload_files: 
    260                 cherrypy.engine.reload_files.append(config) 
     257            cherrypy.engine.publish('Autoreloader', 'add()', config) 
    261258            config = _Parser().dict_from_file(config) 
    262259        elif hasattr(config, 'read'): 
     
    287284        self.namespaces({k: v}) 
    288285 
     286 
     287# Backward compatibility handler for the "engine" namespace. 
     288def _engine_namespace_handler(k, v): 
     289    engine = cherrypy.engine 
     290    if k == 'autoreload_on': 
     291        if v: 
     292            engine.autoreload.attach() 
     293        else: 
     294            engine.autoreload.detach() 
     295    elif k == 'autoreload_frequency': 
     296        engine.publish('Autoreloader', 'frequency', v) 
     297    elif k == 'autoreload_match': 
     298        engine.publish('Autoreloader', 'match', v) 
     299    elif k == 'reload_files': 
     300        engine.publish('Autoreloader', 'files', v) 
     301    elif k == 'deadlock_poll_freq': 
     302        engine.publish('CherryPy Timeout Monitor', 'frequency', v) 
     303    elif k == 'reexec_retry': 
     304        engine.publish('reexec', 'retry', v) 
     305    elif k == 'SIGHUP': 
     306        engine.listeners['SIGHUP'] = set([v]) 
     307    elif k == 'SIGTERM': 
     308        engine.listeners['SIGTERM'] = set([v]) 
     309Config.namespaces["engine"] = _engine_namespace_handler 
    289310 
    290311 
  • trunk/cherrypy/_cpmodpy.py

    r1608 r1627  
    1616 
    1717# We will use this method from the mod_python configuration 
    18 # as the entyr point to our application 
     18# as the entry point to our application 
    1919def setup_server(): 
    2020    cherrypy.tree.mount(Root()) 
     
    2424    # You must start the engine in a non-blocking fashion 
    2525    # so that mod_python can proceed 
    26     cherrypy.engine.start(blocking=False
     26    cherrypy.engine.start(
    2727 
    2828########################################## 
     
    8484                            }) 
    8585     
    86     if cherrypy.engine.state == cherrypy._cpengine.STOPPED: 
    87         cherrypy.engine.start(blocking=False) 
    88     elif cherrypy.engine.state == cherrypy._cpengine.STARTING: 
    89         cherrypy.engine.wait() 
     86    cherrypy.engine.start() 
     87    cherrypy.engine.wait() 
    9088     
    9189    def cherrypy_cleanup(data): 
     
    167165            redirections = [] 
    168166            while True: 
    169                 request = cherrypy.engine.request(local, remote, scheme) 
     167                request = app.get_serving(local, remote, scheme) 
    170168                request.login = req.user 
    171169                request.multithread = bool(threaded) 
     
    179177                    break 
    180178                except cherrypy.InternalRedirect, ir: 
    181                     cherrypy.engine.release() 
     179                    app.release_serving() 
    182180                    prev = request 
    183181                     
     
    199197             
    200198            send_response(req, response.status, response.header_list, response.body) 
    201             cherrypy.engine.release() 
     199            app.release_serving() 
    202200    except: 
    203201        tb = format_exc() 
  • trunk/cherrypy/_cprequest.py

    r1616 r1627  
    394394           "response": response_namespace, 
    395395           "error_page": error_page_namespace, 
    396            # "tools": See _cptools.Toolbox 
     396           "tools": cherrypy.tools, 
    397397           }) 
    398398     
     
    550550                    if self.handler: 
    551551                        cherrypy.response.body = self.handler() 
     552                     
    552553                    self.hooks.run('before_finalize') 
    553554                    cherrypy.response.finalize() 
  • trunk/cherrypy/_cpserver.py

    r1608 r1627  
    9494        for httpserver in self.httpservers: 
    9595            self._start_http(httpserver) 
     96        cherrypy.engine.subscribe('stop', self.stop) 
    9697     
    9798    def _start_http(self, httpserver): 
     
    121122        main thread persists to receive KeyboardInterrupt's. If an 
    122123        exception is raised in the httpserver's thread then it's 
    123         trapped here, and the httpserver(s) and engine are shut down. 
     124        trapped here, and the engine (and therefore our httpservers) 
     125        are shut down. 
    124126        """ 
    125127        try: 
     
    128130            cherrypy.log("<Ctrl-C> hit: shutting down HTTP servers", "SERVER") 
    129131            self.interrupt = exc 
    130             self.stop() 
    131132            cherrypy.engine.stop() 
    132133        except SystemExit, exc: 
    133134            cherrypy.log("SystemExit raised: shutting down HTTP servers", "SERVER") 
    134135            self.interrupt = exc 
    135             self.stop() 
    136136            cherrypy.engine.stop() 
    137137            raise 
     
    155155            # Wait for port to be occupied 
    156156            if isinstance(bind_addr, tuple): 
    157                 wait_for_occupied_port(*bind_addr) 
     157                host, port = bind_addr 
     158                if not host or host == '0.0.0.0': 
     159                    host = socket.gethostname() 
     160                wait_for_occupied_port(host, port) 
    158161     
    159162    def stop(self): 
     
    182185         
    183186        host = self.socket_host 
    184         if not host
     187        if not host or host == '0.0.0.0'
    185188            # The empty string signifies INADDR_ANY. Look up the host name, 
    186189            # which should be the safest thing to spit out in a URL. 
  • trunk/cherrypy/_cptools.py

    r1621 r1627  
    330330     
    331331    This object also functions as a config namespace handler for itself. 
     332    Custom toolboxes should be added to each Application's toolboxes dict. 
    332333    """ 
    333334     
    334335    def __init__(self, namespace): 
    335336        self.namespace = namespace 
    336         cherrypy.engine.request_class.namespaces[namespace] = self 
    337337     
    338338    def __setattr__(self, name, value): 
  • trunk/cherrypy/_cptree.py

    r1612 r1627  
    33import os 
    44import cherrypy 
    5 from cherrypy import _cpconfig, _cplogging, _cpwsgi, tools 
     5from cherrypy import _cpconfig, _cplogging, _cprequest, _cpwsgi, tools 
    66 
    77 
    88class Application(object): 
    99    """A CherryPy Application. 
     10     
     11    Servers and gateways should not instantiate Request objects directly. 
     12    Instead, they should ask an Application object for a request object. 
    1013     
    1114    An instance of this class may also be used as a WSGI callable 
     
    2932     
    3033    namespaces = _cpconfig.NamespaceSet() 
     34    toolboxes = {'tools': cherrypy.tools} 
    3135     
    3236    log = None 
     
    3539    wsgiapp = None 
    3640    wsgiapp__doc = """A CPWSGIApp instance. See _cpwsgi.""" 
     41     
     42    request_class = _cprequest.Request 
     43    response_class = _cprequest.Response 
    3744     
    3845    def __init__(self, root, script_name=""): 
     
    7077        # Handle namespaces specified in config. 
    7178        self.namespaces(self.config.get("/", {})) 
     79     
     80    def get_serving(self, local, remote, scheme, sproto): 
     81        """Create and return a Request and Response object.""" 
     82        req = self.request_class(local, remote, scheme, sproto) 
     83        req.app = self 
     84         
     85        for name, toolbox in self.toolboxes.iteritems(): 
     86            req.namespaces[name] = toolbox 
     87         
     88        resp = self.response_class() 
     89        cherrypy.serving.load(req, resp) 
     90        cherrypy.engine.publish('CherryPy Timeout Monitor', 'acquire()') 
     91        cherrypy.engine.publish('acquire_thread') 
     92         
     93        return req, resp 
     94     
     95    def release_serving(self): 
     96        """Release the current serving (request and response).""" 
     97        req = cherrypy.serving.request 
     98         
     99        cherrypy.engine.publish('CherryPy Timeout Monitor', 'release()') 
     100         
     101        try: 
     102            req.close() 
     103        except: 
     104            cherrypy.log(traceback=True) 
     105         
     106        cherrypy.serving.clear() 
    72107     
    73108    def __call__(self, environ, start_response): 
  • trunk/cherrypy/_cpwsgi.py

    r1608 r1627  
    114114     
    115115    def __init__(self, environ, start_response, cpapp): 
    116         try: 
    117             self.request = self.get_engine_request(environ, cpapp) 
     116        self.cpapp = cpapp 
     117         
     118        try: 
     119            self.request = self.get_request(environ) 
    118120             
    119121            meth = environ['REQUEST_METHOD'] 
     
    193195     
    194196    def close(self): 
    195         _cherrypy.engine.release() 
    196      
    197     def get_engine_request(self, environ, cpapp): 
    198         """Return a Request object from the CherryPy Engine using environ.""" 
     197        """Close and de-reference the current request and response. (Core)""" 
     198        self.cpapp.release_serving() 
     199     
     200    def get_request(self, environ): 
     201        """Create a Request object using environ.""" 
    199202        env = environ.get 
    200203         
     
    206209        scheme = env('wsgi.url_scheme') 
    207210        sproto = env('ACTUAL_SERVER_PROTOCOL', "HTTP/1.1") 
    208         request = _cherrypy.engine.request(local, remote, scheme, sproto) 
     211        request, resp = self.cpapp.get_serving(local, remote, scheme, sproto) 
    209212         
    210213        # LOGON_USER is served by IIS, and is the name of the 
     
    215218        request.multiprocess = environ['wsgi.multiprocess'] 
    216219        request.wsgi_environ = environ 
    217         request.app = cpapp 
    218220        request.prev = env('cherrypy.request') 
    219221        environ['cherrypy.request'] = request 
  • trunk/cherrypy/lib/covercp.py

    r1219 r1627  
    1111To turn on coverage tracing, use the following code: 
    1212 
    13     cherrypy.engine.on_start_engine_list.insert(0, covercp.start) 
    14     cherrypy.engine.on_start_thread_list.insert(0, covercp.start) 
     13    cherrypy.engine.subscribe('start', covercp.start) 
     14    cherrypy.engine.subscribe('start_thread', covercp.start) 
    1515 
    1616Run your code, then use the covercp.serve() function to browse the 
     
    4545    def start(threadid=None): 
    4646        pass 
     47start.priority = 20 
    4748 
    4849# Guess initial depth to hide FIXME this doesn't work for non-cherrypy stuff 
  • trunk/cherrypy/lib/sessions.py

    r1611 r1627  
    2424 
    2525 
    26 class PerpetualTimer(threading._Timer): 
    27      
    28     def run(self): 
    29         while True: 
    30             self.finished.wait(self.interval) 
    31             if self.finished.isSet(): 
    32                 return 
    33             self.function(*self.args, **self.kwargs) 
    34  
    35  
    3626missing = object() 
    3727 
     
    5848     
    5949    clean_thread = None 
    60     clean_thread__doc = "Class-level PerpetualTimer which calls self.clean_up." 
     50    clean_thread__doc = "Class-level Monitor which calls self.clean_up." 
    6151     
    6252    clean_freq = 5 
     
    7565            if self._load() is not None: 
    7666                self.id = None 
    77      
    78     def clean_interrupt(cls): 
    79         """Stop the expired-session cleaning timer.""" 
    80         if cls.clean_thread: 
    81             cls.clean_thread.cancel() 
    82             cls.clean_thread.join() 
    83             cls.clean_thread = None 
    84     clean_interrupt = classmethod(clean_interrupt) 
    8567     
    8668    def clean_up(self): 
     
    130112        cls = self.__class__ 
    131113        if not cls.clean_thread: 
    132             cherrypy.engine.on_stop_engine_list.append(cls.clean_interrupt) 
    133114            # clean_up is in instancemethod and not a classmethod, 
    134115            # so tool config can be accessed inside the method. 
    135             t = PerpetualTimer(self.clean_freq, self.clean_up) 
    136             t.setName("CP Session Cleanup") 
     116            from cherrypy import pywebd 
     117            t = pywebd.plugins.Monitor(cherrypy.engine, self.clean_up, 
     118                                       "CP Session Cleanup") 
     119            t.frequency = self.clean_freq 
    137120            cls.clean_thread = t 
    138121            t.start() 
  • trunk/cherrypy/test/benchmark.py

    r1589 r1627  
    150150 
    151151 
    152 Server Software:        CherryPy/3.0.1alpha 
     152Server Software:        CherryPy/3.1alpha 
    153153Server Hostname:        localhost 
    154154Server Port:            8080 
     
    309309                global AB_PATH 
    310310                AB_PATH = ab_opt 
    311         cherrypy.engine.start(blocking=False
     311        cherrypy.engine.start(
    312312    if cherrypy.engine.state == cherrypy._cpengine.STARTING: 
    313313        cherrypy.engine.wait() 
  • trunk/cherrypy/test/helper.py

    r1528 r1627  
    122122    cherrypy.engine.start_with_callback(_run_test_suite_thread, 
    123123                                        args=(moduleNames, conf)) 
     124    cherrypy.engine.block() 
    124125    if cherrypy.engine.test_success: 
    125126        return 0 
     
    181182        if teardown: 
    182183            teardown() 
    183     thread.interrupt_main() 
     184    cherrypy.engine.stop() 
    184185 
    185186def testmain(conf=None): 
     
    188189        conf = {'server.socket_host': '127.0.0.1'} 
    189190    setConfig(conf) 
    190     try: 
    191         cherrypy.server.quickstart() 
    192         cherrypy.engine.start_with_callback(_test_main_thread) 
    193     except KeyboardInterrupt: 
    194         cherrypy.server.stop() 
    195         cherrypy.engine.stop() 
     191    cherrypy.server.quickstart() 
     192    cherrypy.engine.start_with_callback(_test_main_thread) 
     193    cherrypy.engine.block() 
    196194 
    197195def _test_main_thread(): 
     
    200198        webtest.main() 
    201199    finally: 
    202         thread.interrupt_main() 
    203  
     200        cherrypy.engine.stop() 
     201 
  • trunk/cherrypy/test/modpy.py

    r1568 r1627  
    119119            "environment": "production", 
    120120            }) 
    121         cherrypy.engine.start(blocking=False
     121        cherrypy.engine.start(
    122122    from mod_python import apache 
    123123    return apache.OK 
  • trunk/cherrypy/test/test.py

    r1528 r1627  
    227227            import cherrypy 
    228228            from cherrypy.lib import covercp 
    229             cherrypy.engine.on_start_engine_list.insert(0, covercp.start) 
    230             cherrypy.engine.on_start_thread_list.insert(0, covercp.start) 
     229            cherrypy.engine.hooks['start_process'].insert(0, covercp.start) 
     230            cherrypy.engine.hooks['start_thread'].insert(0, covercp.start) 
    231231        except ImportError: 
    232232            coverage = None 
     
    237237        import cherrypy 
    238238        from cherrypy.lib import covercp 
    239         while covercp.start in cherrypy.engine.on_start_engine_list
    240             cherrypy.engine.on_start_engine_list.remove(covercp.start) 
    241         while covercp.start in cherrypy.engine.on_start_thread_list
    242             cherrypy.engine.on_start_thread_list.remove(covercp.start) 
     239        while covercp.start in cherrypy.engine.hooks['start_process']
     240            cherrypy.engine.hooks['start_process'].remove(covercp.start) 
     241        while covercp.start in cherrypy.engine.hooks['start_thread']
     242            cherrypy.engine.hooks['start_thread'].remove(covercp.start) 
    243243        if self.coverage: 
    244244            self.coverage.save() 
  • trunk/cherrypy/test/test_config.py

    r1620 r1627  
    6161                return value(handler()) 
    6262            cherrypy.request.handler = wrapper 
    63     cherrypy.engine.request_class.namespaces['raw'] = raw_namespace 
    6463     
    6564    class Raw: 
     
    8180    root.foo = Foo() 
    8281    root.raw = Raw() 
    83     cherrypy.tree.mount(root, config=ioconf) 
     82    app = cherrypy.tree.mount(root, config=ioconf) 
     83    app.request_class.namespaces['raw'] = raw_namespace 
     84     
    8485    cherrypy.tree.mount(Another(), "/another") 
    8586    cherrypy.config.update({'environment': 'test_suite'}) 
  • trunk/cherrypy/test/test_states.py

    r1475 r1627  
    2222    ctrlc.exposed = True 
    2323     
    24     def restart(self): 
    25         cherrypy.engine.restart() 
    26         return "app was restarted succesfully" 
    27     restart.exposed = True 
     24    def graceful(self): 
     25        cherrypy.engine.graceful() 
     26        return "app was (gracefully) restarted succesfully" 
     27    graceful.exposed = True 
    2828     
    2929    def block_explicit(self): 
     
    5252        self.running = False 
    5353        self.startcount = 0 
     54        self.gracecount = 0 
    5455        self.threads = {} 
    5556     
     
    6061    def stop(self): 
    6162        self.running = False 
     63     
     64    def graceful(self): 
     65        self.gracecount += 1 
    6266     
    6367    def startthread(self, thread_id): 
     
    8690        # Test server start 
    8791        cherrypy.server.quickstart(self.server_class) 
    88         cherrypy.engine.start(blocking=False
     92        cherrypy.engine.start(
    8993        self.assertEqual(cherrypy.engine.state, 1) 
    9094         
     
    103107        self.assertEqual(len(db_connection.threads), 1) 
    104108         
    105         # Test engine stop 
     109        # Test engine stop. This will also stop the HTTP server. 
    106110        cherrypy.engine.stop() 
    107111        self.assertEqual(cherrypy.engine.state, 0) 
    108112         
    109         # Verify that the on_stop_engine function was called 
     113        # Verify that our custom stop function was called 
    110114        self.assertEqual(db_connection.running, False) 
    111115        self.assertEqual(len(db_connection.threads), 0) 
     
    123127            self.assertBody("Hello World") 
    124128            cherrypy.engine.stop() 
     129        cherrypy.server.start() 
    125130        cherrypy.engine.start_with_callback(stoptest) 
     131        cherrypy.engine.block() 
    126132        self.assertEqual(cherrypy.engine.state, 0) 
    127         cherrypy.server.stop() 
    128133     
    129134    def test_1_Restart(self): 
    130135        cherrypy.server.start() 
    131         cherrypy.engine.start(blocking=False
     136        cherrypy.engine.start(
    132137         
    133138        # The db_connection should be running now 
    134139        self.assertEqual(db_connection.running, True) 
    135         sc = db_connection.startcount 
     140        grace = db_connection.gracecount 
    136141         
    137142        self.getPage("/") 
     
    140145         
    141146        # Test server restart from this thread 
    142         cherrypy.engine.restart() 
     147        cherrypy.engine.graceful() 
    143148        self.assertEqual(cherrypy.engine.state, 1) 
    144149        self.getPage("/") 
    145150        self.assertBody("Hello World") 
    146151        self.assertEqual(db_connection.running, True) 
    147         self.assertEqual(db_connection.startcount, sc + 1) 
     152        self.assertEqual(db_connection.gracecount, grace + 1) 
    148153        self.assertEqual(len(db_connection.threads), 1) 
    149154         
    150155        # Test server restart from inside a page handler 
    151         self.getPage("/restart") 
     156        self.getPage("/graceful") 
    152157        self.assertEqual(cherrypy.engine.state, 1) 
    153         self.assertBody("app was restarted succesfully") 
     158        self.assertBody("app was (gracefully) restarted succesfully") 
    154159        self.assertEqual(db_connection.running, True) 
    155         self.assertEqual(db_connection.startcount, sc + 2) 
     160        self.assertEqual(db_connection.gracecount, grace + 2) 
    156161        # Since we are requesting synchronously, is only one thread used? 
    157         # Note that the "/restart" request has been flushed. 
     162        # Note that the "/graceful" request has been flushed. 
    158163        self.assertEqual(len(db_connection.threads), 0) 
    159164         
     
    162167        self.assertEqual(db_connection.running, False) 
    163168        self.assertEqual(len(db_connection.threads), 0) 
    164         cherrypy.server.stop() 
    165169     
    166170    def test_2_KeyboardInterrupt(self): 
     
    169173            # Raise a keyboard interrupt in the HTTP server's main thread. 
    170174            # We must start the server in this, the main thread 
    171             cherrypy.engine.start(blocking=False
     175            cherrypy.engine.start(
    172176            cherrypy.server.start() 
    173177             
     
    194198            # This should raise a BadStatusLine error, since the worker 
    195199            # thread will just die without writing a response. 
    196             cherrypy.engine.start(blocking=False
     200            cherrypy.engine.start(
    197201            cherrypy.server.start() 
    198202             
     
    211215     
    212216    def test_3_Deadlocks(self): 
    213         cherrypy.engine.start(blocking=False
     217        cherrypy.engine.start(
    214218        cherrypy.server.start() 
    215219        try: 
    216             self.assertNotEqual(cherrypy.engine.monitor_thread, None) 
     220            self.assertNotEqual(cherrypy._timeout_monitor.thread, None) 
    217221             
    218222            # Request a "normal" page. 
    219             self.assertEqual(cherrypy.engine.servings, []) 
     223            self.assertEqual(cherrypy._timeout_monitor.servings, []) 
    220224            self.getPage("/") 
    221225            self.assertBody("Hello World") 
    222226            # request.close is called async. 
    223             while cherrypy.engine.servings: 
     227            while cherrypy._timeout_monitor.servings: 
     228                print ".", 
    224229                time.sleep(0.01) 
    225230             
     
    237242        finally: 
    238243            cherrypy.engine.stop() 
    239             cherrypy.server.stop() 
    240244     
    241245    def test_4_Autoreload(self): 
     
    255259            args.append('-ssl') 
    256260        pid = os.spawnl(os.P_NOWAIT, sys.executable, *args) 
    257         pid = str(pid) 
    258261        cherrypy._cpserver.wait_for_occupied_port(host, port) 
    259262         
    260263        try: 
    261             self.getPage("/pid") 
    262             assert self.body.isdigit(), self.body 
    263             pid = self.body 
     264            self.getPage("/start") 
     265            start = float(self.body) 
    264266             
    265267            # Give the autoreloader time to cache the file time. 
     
    267269             
    268270            # Touch the file 
    269             f = open(demoscript, 'ab') 
    270             f.write(" ") 
    271             f.close() 
     271            os.utime(demoscript, None) 
    272272             
    273273            # Give the autoreloader time to re-exec the process 
     
    276276             
    277277            self.getPage("/pid") 
    278             assert self.body.isdigit(), self.body 
    279             self.assertNotEqual(self.body, pid) 
    280             pid = self.body 
     278            pid = int(self.body) 
     279             
     280            self.getPage("/start") 
     281            self.assert_(float(self.body) > start) 
    281282        finally: 
    282283            # Shut down the spawned process 
     
    289290            except AttributeError: 
    290291                # Windows 
    291                 print os.waitpid(int(pid), 0) 
     292                print os.waitpid(pid, 0) 
    292293        except OSError, x: 
    293294            if x.args != (10, 'No child processes'): 
     
    300301    ServerStateTests.server_class = server 
    301302    suite = helper.CPTestLoader.loadTestsFromTestCase(ServerStateTests) 
     303    engine = cherrypy.engine 
    302304    try: 
    303305        global db_connection 
    304306        db_connection = Dependency() 
    305         cherrypy.engine.on_start_engine_list.append(db_connection.start) 
    306         cherrypy.engine.on_stop_engine_list.append(db_connection.stop) 
    307         cherrypy.engine.on_start_thread_list.append(db_connection.startthread) 
    308         cherrypy.engine.on_stop_thread_list.append(db_connection.stopthread) 
     307        engine.subscribe('start', db_connection.start) 
     308        engine.subscribe('stop', db_connection.stop) 
     309        engine.subscribe('graceful', db_connection.graceful) 
     310        engine.subscribe('start_thread', db_connection.startthread) 
     311        engine.subscribe('stop_thread', db_connection.stopthread) 
    309312         
    310313        try: 
     
    322325                tr.out.close() 
    323326    finally: 
    324         cherrypy.server.stop() 
    325         cherrypy.engine.stop() 
     327        engine.stop() 
    326328 
    327329 
  • trunk/cherrypy/test/test_states_demo.py

    r1476 r1627  
    11import os 
    22import sys 
     3import time 
     4starttime = time.time() 
    35 
    46import cherrypy 
     
    1113    index.exposed = True 
    1214     
     15    def mtimes(self): 
     16        return repr(cherrypy.engine.publish("Autoreloader", "mtimes")) 
     17    mtimes.exposed = True 
     18     
    1319    def pid(self): 
    1420        return str(os.getpid()) 
    1521    pid.exposed = True 
    1622     
     23    def start(self): 
     24        return repr(starttime) 
     25    start.exposed = True 
     26     
    1727    def stop(self): 
    1828        cherrypy.engine.stop() 
    19         cherrypy.server.stop() 
    2029    stop.exposed = True 
    2130 
     
    3847    cherrypy.config.update(conf) 
    3948    cherrypy.tree.mount(Root(), config={'global': conf}) 
    40     cherrypy.engine.start(blocking=False
     49    cherrypy.engine.start(
    4150    cherrypy.server.quickstart() 
    4251    cherrypy.engine.block() 
    43   
  • trunk/cherrypy/test/test_tools.py

    r1621 r1627  
    208208        }, 
    209209    } 
    210     cherrypy.tree.mount(root, config=conf) 
     210    app = cherrypy.tree.mount(root, config=conf) 
     211    app.request_class.namespaces['myauth'] = myauthtools 
    211212 
    212213