class RunScriptCommand(): """ Top class for the hierarchy of the Command in charge of running the scripts of autocorrection for Practices. This should ONLY run the script and capture the results, so that they can be published afterwards when the visitors in the 'publication' package are run. """ TIME_OUT = 60 # seconds def __init__(self): self.script = None self.log = LoggerManager().get_new_logger("run script") def set_script(self, script): self.script = script def execute(self): if(self.script is None): self.log.error("attempt to run the correction process but the script to be run is not defined.") raise IllegalStateException(reason="In order to execute the script, you must set it first.") # now we may call the script self.log.debug("launching correction process...") # FIXME: this is plain shit. We should try to use 'with' automatic_correction_tmp_dir = os.path.dirname(self.script) # managepath.get_instance().get_automatic_correction_tmp_dir() current_dir = os.getcwd() self.log.debug("current dir: %s", current_dir) self.log.debug("script dir : %s", automatic_correction_tmp_dir) os.chdir(automatic_correction_tmp_dir) process = subprocess.Popen([self.script], shell=False, stdout = subprocess.PIPE, stderr=subprocess.PIPE) os.chdir(current_dir) # fin FIXME!!! # must ensure that the process won't run forever process_timer = ProcessTimeout(process, RunScriptCommand.TIME_OUT) process_timer.start_timer() self.log.debug("Process timeout timer launched") # finally, we must capture all results so the can be published script_result = ScriptResult() self.log.debug("waiting for process to finish...") script_result.exit_value = process.wait() self.log.debug("process finished with exit value %d", script_result.exit_value) #if the result has been obtained, the is no point on keeping the timer alive if process_timer.ran: self.log.info("Execution has been terminated for exceding the timeout limit.") else: process_timer.cancel_timer() self.log.debug("Process finished correctly without exceding timeout limit.") output = process.communicate() script_result.captured_stdout = output[0] self.log.debug("stdout captured.") self.log.debug("excecution completed.") return script_result
class LoopRunner(): LOOP_INTERVAL = 65 def __init__(self): logger_manager = LoggerManager() self.log = logger_manager.get_new_logger("loop runner") self.loop_interval = LoopRunner.LOOP_INTERVAL # in seconds self.stdin_path = '/dev/null' self.stdout_path = '/dev/tty' self.stderr_path = '/dev/tty' self.pidfile_path = '/tmp/foo.pid' self.pidfile_timeout = 5 self.automatic_correction_runner = AutomaticCorrectionRunner() self.administrator_mail = AdministratorMail() def stall_loop(self, start_timestamp, finish_timestamp): delta = finish_timestamp - start_timestamp time_to_wait = self.loop_interval - delta.seconds # if the process took less than 30 seconds, we will wait if (time_to_wait > 0): time.sleep(time_to_wait) else: print("not sleeping... delta: " + str(delta)) start_timestamp = datetime.today() def print_result(self, result): # TODO: pass to a log entry print str(datetime.today()) + " | " + str(result) def run(self): self.log = LoggerManager().get_new_logger("daemon control") self.log.info("Daemon's game loop started.") while True: start_timestamp = datetime.today() try: result = self.automatic_correction_runner.run() self.log.info( "Automatic correction process completed.\nResult summary: \n\tsuccessfull: %d\n\tfailed: %d", result[AutomaticCorrectionRunner.SUCCESSFULL_RESULTS_KEY], result[AutomaticCorrectionRunner.FAILED_RESULTS_KEY]) except: self.log.exception( "The automatic correction process failed. Have in mind that is required that the web service must be online." ) try: self.administrator_mail.send_mails() except: self.log.exception( "The mail sending process failed. Have in mind that is required that the web service must be online." ) finish_timestamp = datetime.today() self.stall_loop(start_timestamp, finish_timestamp)
class LoopRunner(): LOOP_INTERVAL = 65 def __init__(self): logger_manager = LoggerManager() self.log = logger_manager.get_new_logger("loop runner") self.loop_interval = LoopRunner.LOOP_INTERVAL # in seconds self.stdin_path = '/dev/null' self.stdout_path = '/dev/tty' self.stderr_path = '/dev/tty' self.pidfile_path = '/tmp/foo.pid' self.pidfile_timeout = 5 self.automatic_correction_runner = AutomaticCorrectionRunner() self.administrator_mail = AdministratorMail() def stall_loop(self, start_timestamp, finish_timestamp): delta = finish_timestamp - start_timestamp time_to_wait = self.loop_interval - delta.seconds # if the process took less than 30 seconds, we will wait if (time_to_wait > 0): time.sleep(time_to_wait) else: print("not sleeping... delta: " + str(delta)) start_timestamp = datetime.today() def print_result(self, result): # TODO: pass to a log entry print str(datetime.today()) + " | " + str(result) def run(self): self.log = LoggerManager().get_new_logger("daemon control") self.log.info("Daemon's game loop started.") while True: start_timestamp = datetime.today() try: result = self.automatic_correction_runner.run() self.log.info("Automatic correction process completed.\nResult summary: \n\tsuccessfull: %d\n\tfailed: %d", result[AutomaticCorrectionRunner.SUCCESSFULL_RESULTS_KEY], result[AutomaticCorrectionRunner.FAILED_RESULTS_KEY]) except: self.log.exception("The automatic correction process failed. Have in mind that is required that the web service must be online.") try: self.administrator_mail.send_mails() except: self.log.exception("The mail sending process failed. Have in mind that is required that the web service must be online.") finish_timestamp = datetime.today() self.stall_loop(start_timestamp, finish_timestamp)
class RunScriptCommand(): """ Top class for the hierarchy of the Command in charge of running the scripts of autocorrection for Practices. This should ONLY run the script and capture the results, so that they can be published afterwards when the visitors in the 'publication' package are run. """ TIME_OUT = 60 # seconds def __init__(self): self.script = None self.log = LoggerManager().get_new_logger("run script") def set_script(self, script): self.script = script def execute(self): if (self.script is None): self.log.error( "attempt to run the correction process but the script to be run is not defined." ) raise IllegalStateException( reason="In order to execute the script, you must set it first." ) # now we may call the script self.log.debug("launching correction process...") # FIXME: this is plain shit. We should try to use 'with' automatic_correction_tmp_dir = os.path.dirname( self.script ) # managepath.get_instance().get_automatic_correction_tmp_dir() current_dir = os.getcwd() self.log.debug("current dir: %s", current_dir) self.log.debug("script dir : %s", automatic_correction_tmp_dir) os.chdir(automatic_correction_tmp_dir) process = subprocess.Popen([self.script], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) os.chdir(current_dir) # fin FIXME!!! # must ensure that the process won't run forever process_timer = ProcessTimeout(process, RunScriptCommand.TIME_OUT) process_timer.start_timer() self.log.debug("Process timeout timer launched") # finally, we must capture all results so the can be published script_result = ScriptResult() self.log.debug("waiting for process to finish...") script_result.exit_value = process.wait() self.log.debug("process finished with exit value %d", script_result.exit_value) #if the result has been obtained, the is no point on keeping the timer alive if process_timer.ran: self.log.info( "Execution has been terminated for exceding the timeout limit." ) else: process_timer.cancel_timer() self.log.debug( "Process finished correctly without exceding timeout limit.") output = process.communicate() script_result.captured_stdout = output[0] self.log.debug("stdout captured.") self.log.debug("excecution completed.") return script_result