Exemplo n.º 1
0
    def _build_state(self, session: Session) -> State:
        db_grant_idle_state_id = session.query(DBGrantState.id).filter(
            DBGrantState.name == GrantStates.IDLE.value,
        ).scalar()
        db_request_pending_state_id = session.query(DBRequestState.id).filter(
            DBRequestState.name == RequestStates.PENDING.value,
        ).scalar()

        # Selectively load sqlalchemy object relations using a single query to avoid commit races.
        # We want to have CBSD entity "grants" relation only contain grants in a Non-IDLE state.
        # We want to have CBSD entity "requests" relation only contain PENDING requests.
        db_configs = session.query(DBActiveModeConfig).join(DBCbsd).options(
            joinedload(DBActiveModeConfig.cbsd).options(
                joinedload(DBCbsd.channels),
                joinedload(
                    DBCbsd.grants.and_(
                        DBGrant.state_id != db_grant_idle_state_id,
                    ),
                ),
                joinedload(
                    DBCbsd.requests.and_(
                        DBRequest.state_id == db_request_pending_state_id,
                    ),
                ),
            ),
        ).filter(*self._get_filter()).populate_existing()
        configs = [self._build_config(db_config) for db_config in db_configs]
        session.commit()
        return State(active_mode_configs=configs)
Exemplo n.º 2
0
 def _build_state(self, session: Session) -> State:
     db_configs = session.query(DBActiveModeConfig).join(DBCbsd).options(
         joinedload(DBActiveModeConfig.cbsd).options(
             joinedload(DBCbsd.channels),
             joinedload(DBCbsd.grants).options(joinedload(DBGrant.state)),
         ), ).filter(*self._get_filter())
     configs = [self._build_config(session, x) for x in db_configs]
     session.commit()
     return State(active_mode_configs=configs)
Exemplo n.º 3
0
    def test_different_processes_dont_pick_up_each_others_requests(
            self, max_batch_size, req_count_1, req_count_2):
        """
        This is a test for horizontal scaling functionality of the Configuration Controller.
        It tests if two processes (in this case associated with different Session instances) only pick those requests
        that have no lock on them.
        """
        # Given
        config = self.get_config()
        config.REQUEST_PROCESSING_LIMIT = max_batch_size
        session1 = Session(bind=self.engine)
        session2 = Session(bind=self.engine)

        consumer = RequestDBConsumer(
            "someRequest",
            request_processing_limit=config.REQUEST_PROCESSING_LIMIT,
        )
        self._prepare_two_pending_and_one_processed_request()

        # When
        reqs1 = consumer.get_pending_requests(session1)
        reqs2 = consumer.get_pending_requests(session2)

        reqs1_list = list(reqs1.values())[0]
        reqs2_list = list(reqs2.values())[0]

        session1.commit()
        session2.commit()

        # Then
        self.assertEqual(req_count_1, len(reqs1_list))
        self.assertEqual(req_count_2, len(reqs2_list))
        if reqs1_list and reqs2_list:
            # Making sure we're not getting the same requests in both sessions
            self.assertNotEqual(reqs1_list[0].cbsd_id, reqs2_list[0].cbsd_id)

        session1.close()
        session2.close()