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 get_status(self): """ get_status() -> Reservation It returns the state of the reservation (such as "you're waiting in a queue", "the experiment is being initialized", "you have the reservation available", etc.) """ try: status = self._coordinator.get_reservation_status( self._reservation_id) except coord_exc.ExpiredSessionError as e: log.log(ReservationProcessor, log.level.Debug, "reason for rejecting:") log.log_exc(ReservationProcessor, log.level.Debug) human = self._cfg_manager.get_doc_value( configuration_doc.CORE_UNIVERSAL_IDENTIFIER_HUMAN) core_id = self._cfg_manager.get_doc_value( configuration_doc.CORE_UNIVERSAL_IDENTIFIER) raise core_exc.NoCurrentReservationError( "get_reservation_status at %s (%s) called but coordinator rejected reservation id (%s). Reason: %s" % (human, core_id, self._reservation_id, str(e))) else: if status.status == scheduling_status.WebLabSchedulingStatus.RESERVED_LOCAL: self.process_reserved_status(status) if status.status == scheduling_status.WebLabSchedulingStatus.RESERVED_REMOTE: self.process_reserved_remote_status(status) return Reservation.Reservation.translate_reservation(status)
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 poll(self): """Inform that it is still online and interested on the reservation""" if not self.is_polling(): raise core_exc.NoCurrentReservationError( "poll called but no current reservation") latest_poll, expiration_time = self._reservation_session[ 'session_polling'] self._reservation_session['session_polling'] = ( self.time_module.time(), expiration_time)
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 _check_reservation_not_expired_and_poll(self, reservation_processor, check_expired = True): if check_expired and reservation_processor.is_expired(): reservation_processor.finish() reservation_id = reservation_processor.get_reservation_id() raise coreExc.NoCurrentReservationError( 'Current user (identified by reservation %r) does not have any experiment assigned' % reservation_id ) try: reservation_processor.poll() except coreExc.NoCurrentReservationError: if check_expired: raise reservation_processor.update_latest_timestamp() # It's already locked, we just update that this user is still among us self._reservations_session_manager.modify_session( reservation_processor.get_reservation_session_id(), reservation_processor.get_session() )
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)