Merge remote-tracking branch 'origin/v3.6'

This commit is contained in:
Adolfo Gómez García 2022-08-30 21:53:42 +02:00
commit b05c5b1396
2 changed files with 39 additions and 19 deletions

View File

@ -67,6 +67,9 @@ from uds.web.util.errors import MAX_SERVICES_REACHED
from .userservice import comms from .userservice import comms
from .userservice.opchecker import UserServiceOpChecker from .userservice.opchecker import UserServiceOpChecker
if typing.TYPE_CHECKING:
from uds import models
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
traceLogger = logging.getLogger('traceLog') traceLogger = logging.getLogger('traceLog')
@ -81,9 +84,8 @@ class UserServiceManager(metaclass=singleton.Singleton):
UserServiceManager() UserServiceManager()
) # Singleton pattern will return always the same instance ) # Singleton pattern will return always the same instance
@staticmethod def getCacheStateFilter(self, servicePool: ServicePool, level: int) -> Q:
def getCacheStateFilter(servicePool: ServicePool, level: int) -> Q: return Q(cache_level=level) & self.getStateFilter(servicePool.service)
return Q(cache_level=level) & UserServiceManager.getStateFilter(servicePool)
@staticmethod @staticmethod
def getStateFilter(servicePool: ServicePool) -> Q: def getStateFilter(servicePool: ServicePool) -> Q:
@ -96,21 +98,37 @@ class UserServiceManager(metaclass=singleton.Singleton):
def _checkMaxDeployedReached(self, servicePool: ServicePool) -> None: def _checkMaxDeployedReached(self, servicePool: ServicePool) -> None:
""" """
Checks if maxDeployed for the service has been reached, and, if so, Returns the number of running user services for this service
raises an exception that no more services of this kind can be reached
""" """
serviceInstance = servicePool.service.getInstance() return UserService.objects.filter(
self.getStateFilter(service) & Q(deployed_service__service=service)
).count()
def maximumUserServicesDeployed(self, service: 'models.Service') -> bool:
"""
Checks if the maximum number of user services for this service has been reached
"""
serviceInstance = service.getInstance()
# Early return, so no database count is needed # Early return, so no database count is needed
if serviceInstance.maxDeployed == services.Service.UNLIMITED: if serviceInstance.maxDeployed == services.Service.UNLIMITED:
return return False
numberOfServices = servicePool.userServices.filter( numberOfServices = servicePool.userServices.filter(
self.getStateFilter(servicePool) self.getStateFilter(servicePool)
).count() ).count()
if serviceInstance.maxDeployed <= numberOfServices: return False
def __checkMaxDeployedReached(self, servicePool: ServicePool) -> None:
"""
Checks if maxDeployed for the service has been reached, and, if so,
raises an exception that no more services of this kind can be reached
"""
if self.maximumUserServicesDeployed(servicePool.service):
raise MaxServicesReachedError( raise MaxServicesReachedError(
'Max number of allowed deployments for service reached' _('Maximum number of user services reached for this {}').format(
servicePool
)
) )
def _createCacheAtDb( def _createCacheAtDb(
@ -532,7 +550,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
if serviceType.usesCache: if serviceType.usesCache:
inAssigned = ( inAssigned = (
servicePool.assignedUserServices() servicePool.assignedUserServices()
.filter(UserServiceManager.getStateFilter(servicePool)) .filter(self.getStateFilter(servicePool.service))
.count() .count()
) )
if ( if (
@ -550,12 +568,14 @@ class UserServiceManager(metaclass=singleton.Singleton):
events.addEvent(servicePool, events.ET_CACHE_MISS, fld1=0) events.addEvent(servicePool, events.ET_CACHE_MISS, fld1=0)
return self.createAssignedFor(servicePool, user) return self.createAssignedFor(servicePool, user)
def getServicesInStateForProvider(self, provider_id: int, state: str) -> int: def getUserServicesInStatesForProvider(
self, provider: 'models.Provider', states: typing.List[str]
) -> int:
""" """
Returns the number of services of a service provider in the state indicated Returns the number of services of a service provider in the state indicated
""" """
return UserService.objects.filter( return UserService.objects.filter(
deployed_service__service__provider__id=provider_id, state=state deployed_service__service__provider=provider, state__in=states
).count() ).count()
def canRemoveServiceFromDeployedService(self, servicePool: ServicePool) -> bool: def canRemoveServiceFromDeployedService(self, servicePool: ServicePool) -> bool:
@ -563,8 +583,8 @@ class UserServiceManager(metaclass=singleton.Singleton):
checks if we can do a "remove" from a deployed service checks if we can do a "remove" from a deployed service
serviceIsntance is just a helper, so if we already have unserialized deployedService serviceIsntance is just a helper, so if we already have unserialized deployedService
""" """
removing = self.getServicesInStateForProvider( removing = self.getUserServicesInStatesForProvider(
servicePool.service.provider.id, State.REMOVING servicePool.service.provider, [State.REMOVING]
) )
serviceInstance = servicePool.service.getInstance() serviceInstance = servicePool.service.getInstance()
if ( if (
@ -579,12 +599,12 @@ class UserServiceManager(metaclass=singleton.Singleton):
""" """
Checks if we can start a new service Checks if we can start a new service
""" """
preparing = self.getServicesInStateForProvider( preparingForProvider = self.getUserServicesInStatesForProvider(
servicePool.service.provider.id, State.PREPARING servicePool.service.provider, [State.PREPARING]
) )
serviceInstance = servicePool.service.getInstance() serviceInstance = servicePool.service.getInstance()
if ( if self.maximumUserServicesDeployed(servicePool.service) or (
preparing >= serviceInstance.parent().getMaxPreparingServices() preparingForProvider >= serviceInstance.parent().getMaxPreparingServices()
and serviceInstance.parent().getIgnoreLimits() is False and serviceInstance.parent().getIgnoreLimits() is False
): ):
return False return False

View File

@ -140,7 +140,7 @@ class ServiceCacheUpdater(Job):
) )
inAssigned: int = ( inAssigned: int = (
servicePool.assignedUserServices() servicePool.assignedUserServices()
.filter(userServiceManager().getStateFilter(servicePool)) .filter(userServiceManager().getStateFilter(servicePool.service))
.count() .count()
) )
# if we bypasses max cache, we will reduce it in first place. This is so because this will free resources on service provider # if we bypasses max cache, we will reduce it in first place. This is so because this will free resources on service provider