Commits

Alessio Deiana committed bf48ada

Ability to connect a python console to worker

* Uses rfoo utils to connect a python console to a running worker
in order to see what is going on

  • Participants
  • Parent commits 48fd48b

Comments (0)

Files changed (3)

File src/invenio_devserver/config.py

 elif 'CFG_INVENIO_SRC' in os.environ:
     SRC_PATH = [os.environ['CFG_INVENIO_SRC']]
 else:
-    SRC_PATH = [ os.path.expanduser("~/src/invenio"), ]
+    SRC_PATH = [os.path.expanduser("~/src/invenio"), ]
 
 
 # Try if we're in a virtualenv or CFG_INVENIO_PREFIX is set.
 CONFIG_FILENAME = 'invenio.conf'
 LOCAL_CONFIG_FILENAME = 'invenio-local.conf'
 
-# Max time we have available to process a request
+# Print a warning after xx seconds when processing a request
 REQUEST_TIMEOUT = 60
 
+# Spawns a server that will accept connections to be able to
+# run arbitrary python code on the work
+USE_CONSOLE = False
+
+
 try:
     import config_local
     for setting in dir(config_local):
             globals()[setting] = getattr(config_local, setting)
 except ImportError:
     pass
-

File src/invenio_devserver/serve.py

 import optparse
 import socket
 import traceback
+import logging
 from itertools import chain
 
 try:
                     _log('info', ' * Detected change in %r' % filename)
                 has_changes = True
 
-
         if has_changes and reloader:
             reloader()
+            if not reloader.worker_pid:
+                return
             time.sleep(1)
 
         time.sleep(interval)
         """Called to reload the worker"""
         if self.worker_pid:
             kill_worker(self.worker_pid)
-        try:
-            self.worker_pid = spawn_server(self.options, self.server_socket)
-        except:
-            # Set to None in case, we kill the whole process group
-            self.worker_pid = None
-            raise
+        self.worker_pid = spawn_server(self.options, self.server_socket)
 
 
 def start_server(options, server_socket, static_files=config.STATIC_FILES):
     wsgi.replace_error_handler()
     wsgi.wrap_warn()
 
+    # Hook debugging console
+    if config.USE_CONSOLE or options.use_console:
+        from rfoo.utils import rconsole
+        rconsole.spawn_server()
+
     static = dict([(k, config.INSTALL_PATH + v) for k, v in static_files.items()])
 
     wsgi_app = partial(wsgi.application, options)
     _log('info', ' * Spawning worker')
     pid = os.fork()
     if pid == 0:
-        start_server(options, server_socket)
+        try:
+            start_server(options, server_socket)
+        except:
+            print traceback.format_exc()[:-1]
+            _log('info', ' * Worker failed to start')
+            # We do not want to free this pid because it will be killed
+            while True:
+                time.sleep(6000)
     return pid
 
 
                       default=[], help='Source folder (one or more)')
     parser.add_option('-o', dest='install_path', metavar='INSTALL_PATH',
                       default=[], help='Path to Invenio installation.')
+    parser.add_option('--use-console', action='store_true', dest='use_console',
+                      default=False, help='Ability to open a remote console on worker')
     return parser.parse_args()
 
 
     return server_socket
 
 
-def prepare_server(options, ssl_context=None):
+def start_reloading_server(options, ssl_context=None):
     """Prepare http server
 
     First binds the socket to accept connections from,
         reloader()
         if reloader.worker_pid:
             invenio_files = list(generate_invenio_files_list())
+            # Our infinite loop is here
             reloader_loop(invenio_files, reloader)
-    except BaseException, e:
+    except BaseException:
         if reloader and reloader.worker_pid:
             kill_worker(reloader.worker_pid)
-        else:
-            # We are killing ourselves
-            # The python interpreter will not get a chance to print
-            # the traceback
-            if not isinstance(e, KeyboardInterrupt) \
-                                            and not isinstance(e, SystemExit):
-                print traceback.format_exc()[:-1]
-            os.killpg(0, signal.SIGKILL)
         raise
 
 
+def setup_logging():
+    logger = logging.getLogger()
+    logger.setLevel(logging.WARNING)
+    handler = logging.StreamHandler()
+    logger.addHandler(handler)
+
+    logger = logging.getLogger('werkzeug')
+    logger.setLevel(logging.INFO)
+    handler = logging.StreamHandler()
+    logger.addHandler(handler)
+    logger.propagate = False
+
+
 def _main():
     """Script entrance"""
+    setup_logging()
     (options, args) = parse_cli_options()
 
     # Override config SRC_PATH and INSTALL_PATH
 
     if options.serve_http and options.auto_reload:
         print 'HTTP Server mode with reload mode'
-        prepare_server(options)
+        start_reloading_server(options)
     elif options.serve_http:
         print 'Simple HTTP Server mode'
         start_server(options, bind_socket(options))
 
 
 if __name__ == '__main__':
-    main()
+    main()

File src/invenio_devserver/wsgi.py

     def final_flush(self):
         pass
 
+raise Exception()
 
 def application(options, environ, start_response):
     """