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_instances(self): status = WSS.WaitingInstancesQueueStatus('foo', 5) reservation = Reservation.translate_reservation(status) self.assertEquals(Reservation.WAITING_INSTANCES, reservation.status) self.assertEquals('foo', reservation.reservation_id.id) self.assertEquals(5, reservation.position) self.assertEquals(status, reservation.to_status())
def test_reject_experiment_voodoo_gen_raises_exception(self): self.mock_locator[coord_addr(self.lab_address)] self.mocker.throw(Exception("Unhandled exception")) self.mocker.replay() status, reservation1_id = self.coordinator.reserve_experiment( ExperimentId('exp1', 'cat1'), 30, 5, True, 'sample initial data', DEFAULT_REQUEST_INFO, {}) self.coordinator.confirmer._confirm_handler.join() self.assertEquals(None, self.confirmer._confirm_handler.raised_exc) status = self.coordinator.get_reservation_status(reservation1_id) expected_status = WSS.WaitingInstancesQueueStatus(reservation1_id, 0) self.assertEquals(expected_status, status)
def test_reject_experiment_laboratory_raises_exception(self): mock_laboratory = self.mocker.mock() mock_laboratory.reserve_experiment(ExperimentInstanceId('inst1','exp1','cat1'), '"sample initial data"', mocker.ANY) self.mocker.throw( Exception("Any unhandled exception") ) self.mock_locator.real_mock = self.mocker.mock() self.mock_locator.real_mock.get_server_from_coordaddress( self.coord_address, coord_addr(self.lab_address), ServerType.Laboratory, 'all' ) self.mocker.result((mock_laboratory,)) self.mocker.replay() status, reservation1_id = self.coordinator.reserve_experiment(ExperimentId('exp1','cat1'), 30, 5, True, 'sample initial data', DEFAULT_REQUEST_INFO, {}) self.coordinator.confirmer._confirm_handler.join() self.assertEquals( None, self.confirmer._confirm_handler.raised_exc ) status = self.coordinator.get_reservation_status(reservation1_id) expected_status = WSS.WaitingInstancesQueueStatus(reservation1_id, 0) self.assertEquals( expected_status, status )
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_instances(self): wi = WSS.WaitingInstancesQueueStatus("reservation_id", 5) str(wi)
def to_status(self): return WSS.WaitingInstancesQueueStatus(self.reservation_id, self.position)