def setUp(self): self.wi_five = WSS.WaitingInstancesQueueStatus("reservation_id", 5) self.wi_four = WSS.WaitingInstancesQueueStatus("reservation_id", 4) self.w_five = WSS.WaitingQueueStatus("reservation_id", 5) self.w_four = WSS.WaitingQueueStatus("reservation_id", 4) self.wc1 = WSS.WaitingConfirmationQueueStatus( "reservation_id", 'http://www.weblab.deusto.es/weblab/client/...') self.wc2 = WSS.WaitingConfirmationQueueStatus( "reservation_id", 'http://www.weblab.deusto.es/weblab/client/...') self.res1 = WSS.LocalReservedStatus( "reservation_id", "coord_address1", "lab_session_id1", {}, 50, None, datetime.datetime.now(), datetime.datetime.now(), True, 50, 'http://www.weblab.deusto.es/weblab/client/foo') self.res2 = WSS.LocalReservedStatus( "reservation_id", "coord_address2", "lab_session_id2", {}, 60, "foo", datetime.datetime.now(), datetime.datetime.now(), True, 50, 'http://www.weblab.deusto.es/weblab/client/foo') self.post1 = WSS.PostReservationStatus("reservation_id", True, "foo1", "bar") self.post2 = WSS.PostReservationStatus("reservation_id", True, "foo2", "bar")
def test_translate_reservation_waiting(self): status = WSS.WaitingQueueStatus('foo', 5) reservation = Reservation.translate_reservation(status) self.assertEquals(Reservation.WAITING, reservation.status) self.assertEquals('foo', reservation.reservation_id.id) self.assertEquals(5, reservation.position) self.assertEquals(status, reservation.to_status())
def reserve_experiment(self, reservation_id, experiment_id, time, priority, initialization_in_accounting, client_initial_data, request_info): if not 'operation' in client_initial_data: raise Exception( "Invalid client_initial_data. If you are using iLab, you should reserve it through /weblab/web/ilab/, or use the same scheme" ) client = self._create_client() if client_initial_data['operation'] == 'get_lab_configuration': config = client.get_lab_configuration() return WSS.PostReservationStatus(reservation_id, True, config, '') elif client_initial_data['operation'] == 'submit': # TODO!!! remote_experiment_id = random.randint(1000000, 200000000) session = self.session_maker() try: reservation = ILabBatchReservation(reservation_id, self.lab_server_url, remote_experiment_id) session.add(reservation) session.commit() finally: session.close() # submit(self, experiment_id, experiment_specification, user_group, priority_hint) experiment_specification = client_initial_data['payload'] accepted, warnings, error, est_runtime, lab_exp_id, min_time_to_live, queue_length, wait = client.submit( remote_experiment_id, experiment_specification, "weblab-deusto", 0) # TODO: do something with the arguments :-) return WSS.WaitingQueueStatus(reservation_id, queue_length) else: raise Exception("Invalid operation in client_initial_data")
def get_reservation_status(self, reservation_id): session = self.session_maker() try: reservation = session.query(ILabBatchReservation).filter_by( local_reservation_id=reservation_id, lab_server_url=self.lab_server_url).first() if reservation is None: # TODO raise Exception("reservation not stored in local database") remote_experiment_id = reservation.remote_experiment_id finally: session.close() # public class StorageStatus # public const int BATCH_QUEUED = 1; // if waiting in the execution queue # public const int BATCH_RUNNING = 2; //if currently running # public const int BATCH_TERMINATED = 3; // if terminated normally # public const int BATCH_TERMINATED_ERROR = 4; // if terminated with errors (this includes cancellation by user in mid-execution) # public const int BATCH_CANCELLED = 5; // if cancelled by user before execution had begun # public const int BATCH_UNKNOWN = 6; // if unknown labExperimentID. # public const int BATCH_NOT_VALID = 7; // Assigned by Service Broker if experiment is not valid (done in submit call) client = self._create_client() code, queue_length, est_wait, est_rt, est_rem_rt, min_to_live = client.get_experiment_status( remote_experiment_id) # TODO do something with the rest of the variables if code == 1: return WSS.WaitingQueueStatus(reservation_id, queue_length) elif code == 2: return WSS.WaitingConfirmationQueueStatus(reservation_id, self.core_server_url) elif code == 3: code, results, xmlResultExtension, xmlBlobExtension, warnings, error = client.retrieve_result( remote_experiment_id) response = json.dumps({ 'code': code, 'results': results, 'xmlResults': xmlResultExtension, }) return WSS.PostReservationStatus(reservation_id, True, response, '') else: return WSS.PostReservationStatus( reservation_id, True, "ERROR: WebLab-Deusto can't handle status code %s at this point" % code, '')
def get_reservation_status(self, reservation_id): self._remove_expired_reservations() try: session = self.session_maker() try: self.reservations_manager.update(session, reservation_id) session.commit() finally: session.close() except StaleDataError: time.sleep(TIME_ANTI_RACE_CONDITIONS * random.random()) return self.get_reservation_status(reservation_id) self._synchronizer.request_and_wait() reservation_id_with_route = '%s;%s.%s' % (reservation_id, reservation_id, self.core_server_route) return_current_status = False session = self.session_maker() try: # # If the current user is actually in a reservation assigned to a # certain laboratory, it may be in a Reserved state or in a # WaitingConfirmation state (meaning that it is still waiting for # a response from the Laboratory). # concrete_current_reservation = session.query(ConcreteCurrentReservation).filter(ConcreteCurrentReservation.current_reservation_id == reservation_id).first() if concrete_current_reservation is not None: resource_instance = concrete_current_reservation.slot_reservation.current_resource_slot.resource_instance requested_experiment_instance = None for experiment_instance in resource_instance.experiment_instances: if experiment_instance.experiment_type == concrete_current_reservation.current_reservation.reservation.experiment_type: requested_experiment_instance = experiment_instance break if requested_experiment_instance is None: raise Exception("Invalid state: there is an resource_instance of the resource_type the user was waiting for which doesn't have any experiment_instance of the experiment_type the user was waiting for") str_lab_coord_address = requested_experiment_instance.laboratory_coord_address lab_coord_address = CoordAddress.translate(str_lab_coord_address) obtained_time = concrete_current_reservation.time lab_session_id = concrete_current_reservation.lab_session_id if concrete_current_reservation.exp_info: exp_info = json.loads(concrete_current_reservation.exp_info) else: exp_info = {} initial_configuration = concrete_current_reservation.initial_configuration initialization_in_accounting = concrete_current_reservation.initialization_in_accounting if concrete_current_reservation.timestamp_before is None: timestamp_before = None else: timestamp_before = datetime.datetime.fromtimestamp(concrete_current_reservation.timestamp_before) if concrete_current_reservation.timestamp_after is None: timestamp_after = None else: timestamp_after = datetime.datetime.fromtimestamp(concrete_current_reservation.timestamp_after) if lab_session_id is None: return WSS.WaitingConfirmationQueueStatus(reservation_id_with_route, self.core_server_url) else: if initialization_in_accounting: before = concrete_current_reservation.timestamp_before else: before = concrete_current_reservation.timestamp_after if before is not None: remaining = (before + obtained_time) - self.time_provider.get_time() else: remaining = obtained_time return WSS.LocalReservedStatus(reservation_id_with_route, lab_coord_address, SessionId.SessionId(lab_session_id), exp_info, obtained_time, initial_configuration, timestamp_before, timestamp_after, initialization_in_accounting, remaining, self.core_server_url) resource_type = session.query(ResourceType).filter_by(name = self.resource_type_name).one() waiting_reservation = session.query(WaitingReservation).filter_by(reservation_id = reservation_id, resource_type_id = resource_type.id).first() if waiting_reservation is None: waiting_reservations = [] else: # # If it has not been assigned to any laboratory, then it might # be waiting in the queue of that resource type (Waiting) or # waiting for instances (WaitingInstances, meaning that there is # no resource of that type implemented) # waiting_reservations = session.query(WaitingReservation)\ .filter(WaitingReservation.resource_type == waiting_reservation.resource_type).order_by(WaitingReservation.priority, WaitingReservation.id).all() if waiting_reservation is None or waiting_reservation not in waiting_reservations: # # The position has changed and it is not in the list anymore! # This has happened using WebLab Bot with 65 users. # return_current_status = True else: position = waiting_reservations.index(waiting_reservation) remaining_working_instances = False for resource_instance in waiting_reservation.resource_type.instances: if resource_instance.slot is not None: remaining_working_instances = True break finally: session.close() if return_current_status: time.sleep(TIME_ANTI_RACE_CONDITIONS * random.random()) return self.get_reservation_status(reservation_id) if remaining_working_instances: return WSS.WaitingQueueStatus(reservation_id_with_route, position) else: return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, position)
def get_reservation_status(self, reservation_id): self._remove_expired_reservations() expired = self.reservations_manager.update(reservation_id) if expired: self._delete_reservation(reservation_id) raise ExpiredSessionError("Expired reservation") self._synchronizer.request_and_wait() reservation_id_with_route = '%s;%s.%s' % ( reservation_id, reservation_id, self.core_server_route) client = self.redis_maker() weblab_reservation_pqueue = WEBLAB_RESOURCE_RESERVATION_PQUEUE % ( self.resource_type_name, reservation_id) reservation_data_str = client.get(weblab_reservation_pqueue) if reservation_data_str is None: log.log( PriorityQueueScheduler, log.level.Error, "get_reservation_status called with a reservation_id that is not registered (not found on weblab_reservation_pqueue). Returning a WaitingInstanceStatus" ) return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, 50) reservation_data = json.loads(reservation_data_str) if ACTIVE_STATUS in reservation_data: # Reserved or Waiting reservation status = reservation_data[ACTIVE_STATUS] # It may be just waiting for the experiment server to respond if status == STATUS_WAITING_CONFIRMATION: return WSS.WaitingConfirmationQueueStatus( reservation_id_with_route, self.core_server_url) # Or the experiment server already responded and therefore we have all this data str_lab_coord_address = reservation_data[LAB_COORD] obtained_time = reservation_data[TIME] initialization_in_accounting = reservation_data[ INITIALIZATION_IN_ACCOUNTING] lab_session_id = reservation_data[LAB_SESSION_ID] initial_configuration = reservation_data[INITIAL_CONFIGURATION] timestamp_before_tstamp = reservation_data[TIMESTAMP_BEFORE] timestamp_after_tstamp = reservation_data[TIMESTAMP_AFTER] if EXP_INFO in reservation_data and reservation_data[EXP_INFO]: exp_info = json.loads(reservation_data[EXP_INFO]) else: exp_info = {} timestamp_before = datetime.datetime.fromtimestamp( timestamp_before_tstamp) timestamp_after = datetime.datetime.fromtimestamp( timestamp_after_tstamp) lab_coord_address = CoordAddress.translate(str_lab_coord_address) if initialization_in_accounting: before = timestamp_before_tstamp else: before = timestamp_after_tstamp if before is not None: remaining = (before + obtained_time) - self.time_provider.get_time() else: remaining = obtained_time return WSS.LocalReservedStatus( reservation_id_with_route, lab_coord_address, SessionId.SessionId(lab_session_id), exp_info, obtained_time, initial_configuration, timestamp_before, timestamp_after, initialization_in_accounting, remaining, self.core_server_url) # else it's waiting weblab_resource_pqueue_map = WEBLAB_RESOURCE_PQUEUE_MAP % self.resource_type_name weblab_resource_pqueue_sorted = WEBLAB_RESOURCE_PQUEUE_SORTED % self.resource_type_name filled_reservation_id = client.hget(weblab_resource_pqueue_map, reservation_id) if filled_reservation_id is None: log.log( PriorityQueueScheduler, log.level.Error, "get_reservation_status called with a reservation_id that is not registered (not found on the reservations map). Returning a WaitingInstanceStatus" ) return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, 50) position = client.zrank(weblab_resource_pqueue_sorted, filled_reservation_id) if position is None: # It's not in the queue now time.sleep(TIME_ANTI_RACE_CONDITIONS * random.random()) return self.get_reservation_status(reservation_id) if self.resources_manager.are_resource_instances_working( self.resource_type_name): return WSS.WaitingQueueStatus(reservation_id_with_route, position) else: return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, position)
def test_str_waiting(self): w = WSS.WaitingQueueStatus("reservation_id", 4) str(w)
def to_status(self): return WSS.WaitingQueueStatus(self.reservation_id, self.position)