1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-30 18:50:20 +03:00

Added atomic transaction to assignations to user from cache, so we ensure that one cached element is assigned to one user and only used once

This commit is contained in:
Adolfo Gómez 2014-05-22 07:48:40 +00:00
parent 4e7376a7f0
commit cf07caa5cb
2 changed files with 29 additions and 13 deletions

View File

@ -6,6 +6,7 @@ encoding//documentation/_downloads/samples/services/SampleUserDeploymentOne.py=u
encoding//documentation/_downloads/samples/services/SampleUserDeploymentTwo.py=utf-8
encoding//documentation/_downloads/samples/services/__init__.py=utf-8
encoding//documentation/conf.py=utf-8
encoding//src/server/enterprise_settings.py=utf-8
encoding//src/server/settings.py=utf-8
encoding//src/server/urls.py=utf-8
encoding//src/uds/REST/__init__.py=utf-8

View File

@ -353,26 +353,41 @@ class UserServiceManager(object):
# return existing[0]
# Now try to locate 1 from cache already "ready" (must be usable and at level 1)
cache = ds.cachedUserServices().select_for_update().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1]
if len(cache) > 0:
cache = cache[0] # Database object
cache.assignToUser(user)
cache.save() # Store assigned ASAP, we do not know how long assignToUser method of instance will take
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]
cache.assignToUser(user)
cache.save() # Store assigned ASAP, we do not know how long assignToUser method of instance will take
else:
cache = None
if cache is not None:
logger.debug('Found a cached-ready service from {0} for user {1}, item {2}'.format(ds, user, cache))
ci = cache.getInstance() # User Deployment instance
ci.assignToUser(user)
cache.updateData(ci)
cache.save()
return cache
# Now find if there is a preparing one
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()
with transaction.atomic():
cache = ds.cachedUserServices().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING)[:1]
if len(cache) > 0:
cache = cache[0]
cache.assignToUser(user)
cache.save()
else:
cache = None
if cache is not None:
logger.debug('Found a cached-preparing service from {0} for user {1}, item {2}'.format(ds, user, cache))
cache.getInstance().assignToUser(user)
ci = cache.getInstance() # User Deployment instance
ci.assignToUser(user)
cache.updateData(ci)
cache.save()
return cache
# Can't assign directly from L2 cache... so we check if we can create e new service in the limits requested
ty = ds.service.getType()
if ty.usesCache is True:
@ -410,7 +425,7 @@ class UserServiceManager(object):
def isReady(self, uService):
UserService.objects.update()
uService = UserService.objects.select_for_update().get(id=uService.id)
uService = UserService.objects.get(id=uService.id)
logger.debug('Checking ready of {0}'.format(uService))
if uService.state != State.USABLE or uService.os_state != State.USABLE:
logger.debug('State is not usable for {0}'.format(uService))
@ -432,7 +447,7 @@ class UserServiceManager(object):
This method is used by UserService when a request for setInUse(False) is made
This checks that the service can continue existing or not
'''
# uService = UserService.objects.select_for_update().get(id=uService.id)
# uService = UserService.objects.get(id=uService.id)
if uService.publication == None:
return
if uService.publication.id != uService.deployed_service.activePublication().id: