def getItems(self, parent: models.ServicePool, item: typing.Optional[str]): # Extract provider try: if not item: return [ AssignedService.itemToDict(k) for k in parent.assignedUserServices().all(). prefetch_related('properties', 'deployed_service', 'publication', 'user') ] return AssignedService.itemToDict( parent.assignedUserServices().get( processUuid(uuid=processUuid(item)))) except Exception: logger.exception('getItems') raise self.invalidItemException()
def getExistingAssignationForUser(self, servicePool: ServicePool, user: User) -> typing.Optional[UserService]: existing = servicePool.assignedUserServices().filter(user=user, state__in=State.VALID_STATES) # , deployed_service__visible=True lenExisting = existing.count() if lenExisting > 0: # Already has 1 assigned logger.debug('Found assigned service from %s to user %s', servicePool, user.name) return existing[0] return None
def getLogs(self, parent: models.ServicePool, item: str) -> typing.List[typing.Any]: try: userService: models.UserService = parent.assignedUserServices( ).get(uuid=processUuid(item)) logger.debug('Getting logs for %s', userService) return log.getLogs(userService) except Exception: raise self.invalidItemException()
def getAssignationForUser( self, servicePool: ServicePool, user: User ) -> typing.Optional[UserService]: # pylint: disable=too-many-branches if servicePool.service.getInstance().spawnsNew is False: assignedUserService = self.getExistingAssignationForUser( servicePool, user) else: assignedUserService = None # If has an assigned user service, returns this without any more work if assignedUserService: return assignedUserService if servicePool.isRestrained(): raise InvalidServiceException( _('The requested service is restrained')) cache: typing.Optional[UserService] = None # Now try to locate 1 from cache already "ready" (must be usable and at level 1) with transaction.atomic(): caches = typing.cast( typing.List[UserService], servicePool.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE, os_state=State.USABLE)[:1]) if caches: cache = caches[0] # Ensure element is reserved correctly on DB if servicePool.cachedUserServices().select_for_update().filter( user=None, uuid=typing.cast( UserService, cache).uuid).update( user=user, cache_level=0) != 1: cache = None else: cache = None # Out of previous atomic if not cache: with transaction.atomic(): caches = typing.cast( typing.List[UserService], servicePool.cachedUserServices().select_for_update(). filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1]) if cache: cache = caches[0] if servicePool.cachedUserServices().select_for_update( ).filter(user=None, uuid=typing.cast(UserService, cache).uuid).update( user=user, cache_level=0) != 1: cache = None else: cache = None # Out of atomic transaction if cache: # Early assign cache.assignToUser(user) logger.debug( 'Found a cached-ready service from %s for user %s, item %s', servicePool, user, cache) events.addEvent(servicePool, events.ET_CACHE_HIT, fld1=servicePool.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE).count()) return cache # Cache missed # Now find if there is a preparing one with transaction.atomic(): caches = servicePool.cachedUserServices().select_for_update( ).filter(cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING)[:1] if caches: cache = caches[0] if servicePool.cachedUserServices().select_for_update().filter( user=None, uuid=typing.cast( UserService, cache).uuid).update( user=user, cache_level=0) != 1: cache = None else: cache = None # Out of atomic transaction if cache: cache.assignToUser(user) logger.debug( 'Found a cached-preparing service from %s for user %s, item %s', servicePool, user, cache) events.addEvent(servicePool, events.ET_CACHE_MISS, fld1=servicePool.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING).count()) return cache # Can't assign directly from L2 cache... so we check if we can create e new service in the limits requested serviceType = servicePool.service.getType() if serviceType.usesCache: # inCacheL1 = ds.cachedUserServices().filter(UserServiceManager.getCacheStateFilter(services.UserDeployment.L1_CACHE)).count() inAssigned = servicePool.assignedUserServices().filter( UserServiceManager.getStateFilter()).count() # totalL1Assigned = inCacheL1 + inAssigned if inAssigned >= servicePool.max_srvs: # cacheUpdater will drop unnecesary L1 machines, so it's not neccesary to check against inCacheL1 log.doLog( servicePool, log.WARN, 'Max number of services reached: {}'.format( servicePool.max_srvs), log.INTERNAL) raise MaxServicesReachedError() # Can create new service, create it events.addEvent(servicePool, events.ET_CACHE_MISS, fld1=0) return self.createAssignedFor(servicePool, user)