diff --git a/server/.pydevproject b/server/.pydevproject index 280f5e7c..e235b96a 100644 --- a/server/.pydevproject +++ b/server/.pydevproject @@ -1,6 +1,6 @@ -Default +uds 2.2 python 2.7 DJANGO_MANAGE_LOCATION diff --git a/server/src/uds/core/managers/UserServiceManager.py b/server/src/uds/core/managers/UserServiceManager.py index 2c4e88c7..f812cda9 100644 --- a/server/src/uds/core/managers/UserServiceManager.py +++ b/server/src/uds/core/managers/UserServiceManager.py @@ -51,7 +51,7 @@ import requests import json import logging -__updated__ = '2018-09-24' +__updated__ = '2019-02-22' logger = logging.getLogger(__name__) traceLogger = logging.getLogger('traceLog') @@ -267,15 +267,28 @@ class UserServiceManager(object): # Now try to locate 1 from cache already "ready" (must be usable and at level 1) with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE, os_state=State.USABLE)[:1] - if len(cache) == 0: - cache = ds.cachedUserServices().select_for_update().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1] - if len(cache) > 0: + if len(cache) != 0: cache = cache[0] - cache.assignToUser(user) - cache.save() # Store assigned ASAP, we do not know how long assignToUser method of instance will take + # Ensure element is reserved correctly on DB + if ds.cachedUserServices().select_for_update().filter(uuid=cache.uuid).update(user=user, cache_level=0) != 1: + cache = None else: cache = None + if cache == None: + with transaction.atomic(): + cache = ds.cachedUserServices().select_for_update().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1] + if len(cache) > 0: + cache = cache[0] + if ds.cachedUserServices().select_for_update().filter(uuid=cache.uuid).update(user=user, cache_level=0) != 1: + cache = None + else: + cache = None + + if cache: + cache.assignToUser(user) + cache.save() # Store assigned ASAP, we do not know how long assignToUser method of instance will take + # Out of atomic transaction if cache is not None: logger.debug('Found a cached-ready service from {0} for user {1}, item {2}'.format(ds, user, cache)) @@ -293,8 +306,11 @@ class UserServiceManager(object): cache = ds.cachedUserServices().select_for_update().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING)[:1] if len(cache) > 0: cache = cache[0] - cache.assignToUser(user) - cache.save() + if ds.cachedUserServices().select_for_update().filter(uuid=cache.uuid).update(user=user, cache_level=0) != 1: + cache = None + else: + cache.assignToUser(user) + cache.save() else: cache = None diff --git a/server/src/uds/models/ServicesPool.py b/server/src/uds/models/ServicesPool.py index 54b036b0..899611ce 100644 --- a/server/src/uds/models/ServicesPool.py +++ b/server/src/uds/models/ServicesPool.py @@ -62,7 +62,7 @@ import logging import pickle import six -__updated__ = '2018-06-21' +__updated__ = '2019-02-22' logger = logging.getLogger(__name__) @@ -442,7 +442,7 @@ class DeployedService(UUIDModel, TaggingMixin): Returns: A list of db records (userService) with cached user services ''' - return self.userServices.exclude(cache_level=0) + return self.userServices.exclude(cache_level=0, user=None) def assignedUserServices(self): '''