def __call__(self, application=None, appdir=None, bind=None, forks=None, handle_errors=True, cli=True, config=None, pidfile=None, chdir=None, umask=None, spawn=None, *args, **kwargs): '''Helper for setting up and running an application. If several servers are spawned a list of PIDs is returned, otherwise whatever returned by application.run() is returned. ''' stdout = stderr = http_addr = None debug = False http_port = 0 if cli: appdir, bind, forks, spawn, chdir, umask, stdout, stderr, pidfile, http_port, http_addr, debug \ = main_cli_filter(appdir=appdir, bind=bind, forks=forks) # Setup if handle_errors: application = handle_errors_wrapper(self.setup, application=application, appdir=appdir, config=config, *args, **kwargs) else: application = self.setup(application=application, appdir=appdir, config=config, *args, **kwargs) if debug: _config.loads("'logging': {'levels':{'':'DEBUG'}}") # Pidfile? if pidfile: self.pidfile = pidfile try: open(self.pidfile, 'w').close() except: pass # Run method kewyords run_kwargs = dict(bind=bind, application=application, forks=forks, handle_errors=handle_errors) # Spawn? if spawn: def childfunc(childno, bindarg): _chdir = chdir # ref workaround print 'server %d starting at %s' % (os.getpid(), bindarg) if _chdir is None: _chdir = '/' daemonize(chdir, umask, '/dev/null', stdout, stderr) run_kwargs['bind'] = bindarg self.run(**run_kwargs) socket, startport, address, args = parse_bind_arg(bind) childs = fork_binds(spawn, childfunc, socket=socket, startport=startport, address=address) return childs else: _prepare_env(chdir=chdir, umask=umask) if http_port or http_addr != None: # start the http server from smisk.util.httpd import Server if http_addr == None: http_addr = 'localhost' elif http_addr == '*': http_addr = '' if not http_port: http_port = 8080 http_addr = (http_addr, http_port) fcgi_addr = ('127.0.0.1', 5990) server = Server(http_addr, fcgi_addr) orig_sighandlers = {} def kill_app_sighandler(signum, frame): try: print 'sending SIGKILL to application %d...' % app_pid log.debug('sending SIGKILL to application %d...', app_pid) os.kill(app_pid, 9) except: pass def sighandler(signum, frame): try: print 'sending signal %d to application %d...' % ( signum, app_pid) log.debug('sending signal %d to application %d...', signum, app_pid) os.kill(app_pid, signum) except: pass try: orig_alarm_handler = signal.signal(signal.SIGALRM, kill_app_sighandler) signal.alarm(2) # 2 sec delay until SIGKILLing os.waitpid(-1, 0) signal.alarm(0) # cancel SIGKILL signal.signal(signal.SIGALRM, orig_alarm_handler) except: pass try: orig_sighandlers[signum](signum, frame) except: pass signal.signal(signal.SIGALRM, lambda x,y: os._exit(0)) signal.alarm(2) # 2 sec time limit for cleanup functions sys.exit(0) log_level = logging.INFO if debug: log_level = logging.DEBUG logging.basicConfig(level=log_level) orig_sighandlers[signal.SIGINT] = signal.signal(signal.SIGINT, sighandler) orig_sighandlers[signal.SIGTERM] = signal.signal(signal.SIGTERM, sighandler) orig_sighandlers[signal.SIGHUP] = signal.signal(signal.SIGHUP, sighandler) # fork off the app run_kwargs['bind'] = '127.0.0.1:5990' app_pid = self.run_deferred(**run_kwargs) # start the web server print 'httpd listening on %s:%d backed by application %d' % (http_addr[0], http_addr[1], app_pid) server.serve_forever() os.kill(os.getpid(), 2) os.kill(os.getpid(), 15) else: # Run return self.run(**run_kwargs)
dict = dict( str = "<hello & hi there!>", unicode = u'M\xe4ssig, Ma\xdf', true_value = True, false_value = False, ), data = data("<binary gunk>"), more_data = data("<lots of binary gunk>" * 10), date = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), ) # Our controller tree class root(Controller): def __call__(self, *args, **params): '''Return some data ''' return DEMO_STRUCT def echo(self, *va, **kw): '''Returns the structure received ''' if not kw and va: kw['arguments'] = va return kw if __name__ == '__main__': from smisk.config import config config.loads('"logging": {"levels":{"":DEBUG}}') main()