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)
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)
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()