예제 #1
0
    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")
예제 #2
0
    def test_confirm_experiment(self):
        lab_session_id = SessionId.SessionId("samplesession_id")

        mock_laboratory = self.mocker.mock()
        mock_laboratory.reserve_experiment(ExperimentInstanceId('inst1','exp1','cat1'), '"sample initial data"', mocker.ANY)
        self.mocker.result((lab_session_id, None, 'server:inst@mach'))

        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.count(min=1,max=None)

        self.mocker.replay()
        status, reservation1_id = self.coordinator.reserve_experiment(ExperimentId('exp1','cat1'), 30, 5, True, 'sample initial data', DEFAULT_REQUEST_INFO, {})
        now = datetime.datetime.fromtimestamp(int(time.time())) # Remove milliseconds as MySQL do
        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.LocalReservedStatus(reservation1_id, CoordAddress.CoordAddress.translate_address(self.lab_address), lab_session_id, 30, '{}', now, now, True, 30, 'http://www.weblab.deusto.es/weblab/client/adfas')

        self.assertTrue(hasattr(status, 'timestamp_before'),  "Unexpected status. Expected\n %s\n, but the obtained does not have timestamp_before:\n %s\n" % (status, expected_status))
        self.assertTrue(status.timestamp_before >= now and status.timestamp_before <= now + datetime.timedelta(seconds=10),
                        "Unexpected status due to timestamp_before: %s; expected something like %s" % (status, expected_status))
        self.assertTrue(status.timestamp_after  >= now and status.timestamp_after  <= now + datetime.timedelta(seconds=10),
                        "Unexpected status due to timestamp_after: %s; expected something like %s" % (status, expected_status))

        status.timestamp_before = now
        status.timestamp_after = now
        self.assertEquals( expected_status, status )
예제 #3
0
 def test_str_local_reservation(self):
     res = WSS.LocalReservedStatus(
         "reservation_id", "coord_address1", "lab_session_id1", 50, None,
         datetime.datetime.now(), datetime.datetime.now(), True, 45,
         'http://www.weblab.deusto.es/weblab/client/#reservation-id=foo&...'
     )
     str(res)
예제 #4
0
    def test_translate_local_reservation_reserved(self):
        status = WSS.LocalReservedStatus('foo', 'i:s@m',
                                         'lab_session', 100, "{}", time.time(),
                                         time.time(), True, 80, 'http://...')
        reservation = Reservation.translate_reservation(status)
        self.assertEquals(Reservation.CONFIRMED, reservation.status)
        self.assertEquals('foo', reservation.reservation_id.id)
        self.assertEquals('http://...', reservation.url)
        self.assertEquals('{}', reservation.initial_configuration)

        status = WSS.RemoteReservedStatus('foo', 80, '{}', 'http://...', '')
        self.assertEquals(status, reservation.to_status())
예제 #5
0
    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)