def fork_and_run_one(self, run_argv, app_name, app_argv): app_color = next(self.app_colors) pid = fork() if pid > 0: return pid os.setsid() ColoredFormatter.app_color = app_color result = self.run_one(run_argv, app_name, app_argv) sys.exit(result)
def run_with_reloader(main_func, extra_files=None, interval=1): """ Run the given function in an independent python interpreter. """ log.info('running with reloader...') while 1: pid = fork() if pid == 0: ready_queue = Queue() gevent.spawn(run_and_push_result, ready_queue, main_func, ()) gevent.spawn(run_and_push_result, ready_queue, reloader_loop, (extra_files, interval)) sys.exit(ready_queue.get()) try: pid, code_sig = os.waitpid(pid, 0) exit_code = code_sig >> 8 except KeyboardInterrupt: exit_code = 4 if exit_code != 3: return exit_code
def run_many(self, argv=None): if argv is None: argv = sys.argv run_argv, app_argvs = self.parse_argv(argv) ret = self.handle_argv(run_argv) if ret is not None: return ret if not app_argvs: self.usage(argv) return 1 class RUN_SETTINGS: log_to_hub = False logging_settings = SettingsWrapper(RUN_SETTINGS, self.settings) setup_logging("run", logging_settings) # Check to see if we're running a script if "/" in app_argvs[0][0]: # XXX: Hack. Not sure how we want to rewrite sys.argv in the case # of running scripts (which don't fork, so can't have multiple # things running, so the argv parsing we did above is partially # moot) argv[0] = "%s %s" % (run_argv[0], app_argvs[0][0]) script_path = argv.pop(len(run_argv)) return self.run_script(script_path) app_names_settings = [(app_argv[0], self.get_app_settings(app_argv[0]), app_argv[1:]) for app_argv in app_argvs] self._get_api_force_no_mock.update(argv[1:]) app_colors = iter(itertools.cycle(["blue", "magenta", "cyan", "green", "grey", "white"])) pid = -1 try: app_pids = {} for app_name, app_settings, app_argv in app_names_settings: app_color = next(app_colors) pid = fork() if pid > 0: app_pids[pid] = app_name else: os.setsid() ColoredFormatter.app_color = app_color return self.run_app(app_name, app_settings, app_argv) while app_pids: try: child, status_sig = os.waitpid(-1, 0) status = status_sig >> 8 except KeyboardInterrupt: status = 4 if status == 99: app_pids.pop(child, None) status = 0 continue if status != 4: log_message = (status == 0) and log.info or log.warning log_message("app %s exited with status %s", app_pids.get(child, child), status) break finally: pids_to_kill = (pid > 0) and app_pids.keys() or [] for pid_to_kill in pids_to_kill: try: os.killpg(pid_to_kill, signal.SIGTERM) except OSError as e: # errno 3 == "ESRCH" (not found), and we expect to get at least # one of those when we exit as a result of one of the # apps exiting. # errno 1 == "EPERM" (permision denied), and this seems # to be related to a specific "issue" related to killing # process groups which contain zombies on Darwin/BSD. It # doesn't seem to come up on Linux, though, and so should # be safe to ignore. # See discussion: http://stackoverflow.com/q/12521705/71522 if e.errno not in [1, 3]: log.error("killing %r: %s", pid_to_kill, e) return status
def run_many(self, argv=None): if argv is None: argv = sys.argv run_argv, app_argvs = self.parse_argv(argv) ret = self.handle_argv(run_argv) if ret is not None: return ret if not app_argvs: self.usage(argv) return 1 class RUN_SETTINGS: log_to_hub = False logging_settings = SettingsWrapper(RUN_SETTINGS, self.settings) setup_logging("run", logging_settings) # Check to see if we're running a script if "/" in app_argvs[0][0]: # XXX: Hack. Not sure how we want to rewrite sys.argv in the case # of running scripts (which don't fork, so can't have multiple # things running, so the argv parsing we did above is partially # moot) argv[0] = "%s %s" % (run_argv[0], app_argvs[0][0]) script_path = argv.pop(len(run_argv)) return self.run_script(script_path) app_names_settings = [ (app_argv[0], self.get_app_settings(app_argv[0]), app_argv[1:]) for app_argv in app_argvs ] self._get_api_force_no_mock.update(argv[1:]) app_colors = iter(itertools.cycle( ["blue", "magenta", "cyan", "green", "grey", "white"] )) pid = -1 try: app_pids = {} for app_name, app_settings, app_argv in app_names_settings: app_color = next(app_colors) pid = fork() if pid > 0: app_pids[pid] = app_name else: os.setsid() ColoredFormatter.app_color = app_color return self.run_app(app_name, app_settings, app_argv) while app_pids: try: child, status_sig = os.waitpid(-1, 0) status = status_sig >> 8 except KeyboardInterrupt: status = 4 if status == 99: app_pids.pop(child, None) status = 0 continue if status != 4: log_message = (status == 0) and log.info or log.warning log_message("app %s exited with status %s", app_pids.get(child, child), status) break finally: pids_to_kill = (pid > 0) and app_pids.keys() or [] for pid_to_kill in pids_to_kill: try: os.killpg(pid_to_kill, signal.SIGTERM) except OSError as e: # errno 3 == "ESRCH" (not found), and we expect to get at least # one of those when we exit as a result of one of the # apps exiting. # errno 1 == "EPERM" (permision denied), and this seems # to be related to a specific "issue" related to killing # process groups which contain zombies on Darwin/BSD. It # doesn't seem to come up on Linux, though, and so should # be safe to ignore. # See discussion: http://stackoverflow.com/q/12521705/71522 if e.errno not in [1, 3]: log.error("killing %r: %s", pid_to_kill, e) return status