def send_async_file(self, file_content, file_info): """ Sends a file asynchronously. Status of the request may be checked through check_async_command_status. @param file_content: Content of the file being sent @param file_info: File information of the file being sent @see check_async_command_status """ lab_session_id = self._reservation_session.get('lab_session_id') lab_coordaddr = self._reservation_session.get('lab_coordaddr') if lab_session_id is None or lab_coordaddr is None: raise core_exc.NoCurrentReservationError( "send_async_file called but no current reservation") laboratory_server = self._locator.get_server_from_coordaddr( lab_coordaddr, ServerType.Laboratory) usage_file_sent = self._store_file(file_content, file_info) command_id_pack = self._append_file(usage_file_sent) try: response = laboratory_server.send_async_file( lab_session_id, file_content, file_info) # TODO: how do we store async files? whenever somebody ask for the status? what if they don't ask for it? return response except LaboratoryErrors.SessionNotFoundInLaboratoryServerError: self._update_command_or_file( command_id_pack, Command.Command("ERROR: SessionNotFound: None")) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.NoCurrentReservationError( 'Experiment reservation expired') except LaboratoryErrors.FailedToInteractError as ftspe: self._update_command_or_file( command_id_pack, Command.Command("ERROR: " + str(ftspe))) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.FailedToInteractError("Failed to send file: %s" % ftspe)
def send_command(self, command): # # Check the that the experiment is enabled # lab_session_id = self._reservation_session.get('lab_session_id') lab_coordaddr = self._reservation_session.get('lab_coordaddr') if lab_session_id is None or lab_coordaddr is None: raise core_exc.NoCurrentReservationError( "send_command called but the reservation is not enabled") laboratory_server = self._locator.get_server_from_coordaddr( lab_coordaddr, ServerType.Laboratory) command_id_pack = self._append_command(command) try: # We call the laboratory server's send_command, which will finally # get the command to be handled by the experiment. response = laboratory_server.send_command(lab_session_id, command) # The previous call was executed synchronously and we have # received the response. Before returning it, we will store it # locally so that we can log it. self._update_command_or_file(command_id_pack, response) return response except LaboratoryErrors.SessionNotFoundInLaboratoryServerError: self._update_command_or_file( command_id_pack, Command.Command("ERROR: SessionNotFound: None")) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.NoCurrentReservationError( 'Experiment reservation expired') except LaboratoryErrors.FailedToInteractError as ftspe: self._update_command_or_file( command_id_pack, Command.Command("ERROR: " + str(ftspe))) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.FailedToInteractError("Failed to send command: %s" % ftspe)
def send_file(self, file_content, file_info): # # Check that the reservation is enabled # lab_session_id = self._reservation_session.get('lab_session_id') lab_coordaddr = self._reservation_session.get('lab_coordaddr') if lab_session_id is None or lab_coordaddr is None: raise core_exc.NoCurrentReservationError( "send_file called but the reservation was not enabled") # # Retrieve the laboratory server # laboratory_server = self._locator.get_server_from_coordaddr( lab_coordaddr, ServerType.Laboratory) usage_file_sent = self._store_file(file_content, file_info) command_id_pack = self._append_file(usage_file_sent) try: response = laboratory_server.send_file(lab_session_id, file_content, file_info) self._update_command_or_file(command_id_pack, response) return response except LaboratoryErrors.SessionNotFoundInLaboratoryServerError: self._update_command_or_file( command_id_pack, Command.Command("ERROR: SessionNotFound")) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.NoCurrentReservationError( 'Experiment reservation expired') except LaboratoryErrors.FailedToInteractError as ftie: self._update_command_or_file( command_id_pack, Command.Command("ERROR: " + str(ftie))) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.FailedToInteractError("Failed to send: %s" % ftie)
def send_async_command(self, command): """ Runs a command asynchronously. Status of the request may be checked through the check_async_command_status method. @param command The command to run @see check_async_command_status """ lab_session_id = self._reservation_session.get('lab_session_id') lab_coordaddr = self._reservation_session.get('lab_coordaddr') if lab_session_id is None or lab_coordaddr is None: raise core_exc.NoCurrentReservationError( "send_async_command called but no current reservation") command_id_pack = self._append_command(command) try: laboratory_server = self._locator[lab_coordaddr] # We forward the request to the laboratory server, which # will forward it to the actual experiment. Because this is # an asynchronous call, we will not receive the actual response # to the command, but simply an ID identifying our request. This also # means that by the time this call returns, the real response to the # command is most likely not available yet. request_id = laboratory_server.send_async_command( lab_session_id, command) # If this was a standard, synchronous send_command, we would now store the response # we received, so that later, when the experiment finishes, the log is properly # written. However, the real response is not available yet, so we can't do that here. # Instead, we will store a reference to our usage object, so that we can later update it # when the response to the asynchronous command is ready. self._reservation_session["async_commands_ids"][ request_id] = command_id_pack # TODO: when do we store async commands? whenever user asks for status? what if they don't ever ask? return request_id except LaboratoryErrors.SessionNotFoundInLaboratoryServerError: self._update_command_or_file( command_id_pack, Command.Command("ERROR: SessionNotFound: None")) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.NoCurrentReservationError( 'Experiment reservation expired') except LaboratoryErrors.FailedToInteractError as ftspe: self._update_command_or_file( command_id_pack, Command.Command("ERROR: " + str(ftspe))) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.FailedToInteractError("Failed to send command: %s" % ftspe)
def check_async_command_status(self, request_identifiers): """ Checks the status of several asynchronous commands. The request will be internally forwarded to the lab server. Standard async commands and file_send commands are treated in the same way. Commands reported as finished (either successfully or not) will be removed, so check_async_command_status should not be called on them again. Before removing the commands, it will also register their response for logging purposes. @param request_identifiers: List of the identifiers to check @return: Dictionary by request-id of tuples: (status, content) """ lab_session_id = self._reservation_session.get('lab_session_id') lab_coordaddr = self._reservation_session.get('lab_coordaddr') if lab_session_id is None or lab_coordaddr is None: raise core_exc.NoCurrentReservationError( "check_async_command called but no current reservation") try: laboratory_server = self._locator[lab_coordaddr] response = laboratory_server.check_async_command_status( lab_session_id, request_identifiers) # Within the response map, we might now have the real response to one # (or more) async commands. We will update the usage object of the # command with its response, so that once the experiment ends it appears # in the log as expected. for req_id, (cmd_status, cmd_response) in response.items(): #@UnusedVariable if (req_id in self._reservation_session["async_commands_ids"]): #usage_obj_id = self._reservation_session["async_commands_ids"][req_id] # TODO: Bug here. async_commands_ids is empty. # self._update_command_or_file(usage_obj_id, cmd_response) pass return response except LaboratoryErrors.SessionNotFoundInLaboratoryServerError: # We did not find the specified session in the laboratory server. # We'll finish the experiment. #self._update_command(command_id_pack, Command.Command("ERROR: SessionNotFound: None")) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.NoCurrentReservationError( 'Experiment reservation expired') except LaboratoryErrors.FailedToInteractError as ftspe: # There was an error while trying to send the command. # We'll finish the experiment. #self._update_command(command_id_pack, Command.Command("ERROR: " + str(ftspe))) try: self.finish() except core_exc.FailedToFreeReservationError: pass raise core_exc.FailedToInteractError("Failed to send command: %s" % ftspe)