mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-22 13:34:04 +03:00
Adding support for returning back to cache
This commit is contained in:
parent
0a39939659
commit
7c2a8168fa
@ -670,12 +670,9 @@ class Logout(ActorV3Action):
|
||||
|
||||
if userservice.in_use: # If already logged out, do not add a second logout (windows does this i.e.)
|
||||
osmanagers.OSManager.logged_out(userservice, username)
|
||||
if osmanager:
|
||||
if osmanager.is_removable_on_logout(userservice):
|
||||
logger.debug('Removable on logout: %s', osmanager)
|
||||
userservice.release()
|
||||
else:
|
||||
userservice.release()
|
||||
# If does not have osmanager, or has osmanager and is removable, release it
|
||||
if not osmanager or osmanager.is_removable_on_logout(userservice):
|
||||
UserServiceManager.manager().release_on_logout(userservice)
|
||||
|
||||
def action(self) -> dict[str, typing.Any]:
|
||||
is_managed = self._params.get('type') != consts.actor.UNMANAGED
|
||||
|
@ -302,24 +302,29 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
# Data will be serialized on makeUnique process
|
||||
UserServiceOpChecker.make_unique(cache, cache_instance, state)
|
||||
|
||||
def clone_userservice_as_cache(self, user_service: UserService) -> UserService:
|
||||
def forced_move_assigned_to_cache_l1(self, user_service: UserService) -> None:
|
||||
"""
|
||||
Clones the record of a user service, cleaning up some fields so it's a cache element
|
||||
The uuid will be regenerated, and the pk will be set to None
|
||||
Clones the record of a user serviceself.
|
||||
For this, the original userservice will ve moved to cache, and a new one will be created
|
||||
to mark it as "REMOVED"
|
||||
"""
|
||||
# Load as new variable to avoid modifying original
|
||||
user_service = UserService.objects.get(id=user_service.id)
|
||||
user_service.pk = None
|
||||
user_service.uuid = generate_uuid()
|
||||
user_service_copy = UserService.objects.get(id=user_service.id)
|
||||
user_service_copy.pk = None
|
||||
user_service_copy.uuid = generate_uuid()
|
||||
user_service_copy.in_use = False
|
||||
user_service_copy.state = State.REMOVED
|
||||
user_service_copy.os_state = State.USABLE
|
||||
|
||||
# Save the new element, for reference
|
||||
user_service_copy.save()
|
||||
|
||||
# Now, move the original to cache, but do it "hard" way, so we do not need to check for state
|
||||
user_service.state = State.USABLE
|
||||
user_service.os_state = State.USABLE
|
||||
user_service.user = None
|
||||
user_service.cache_level = types.services.CacheLevel.L1
|
||||
user_service.in_use = False
|
||||
user_service.state = State.USABLE # We set it to usable so it can be used directly...
|
||||
user_service.os_state = State.USABLE
|
||||
|
||||
# Save the new cache element
|
||||
user_service.save()
|
||||
return user_service
|
||||
|
||||
def get_cache_servicepool_stats(self, servicepool: ServicePool) -> 'types.services.ServicePoolStats':
|
||||
"""
|
||||
@ -484,7 +489,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
_('Can\'t remove nor cancel {} cause its state don\'t allow it').format(user_service.name)
|
||||
)
|
||||
|
||||
def release_on_logout(self, user_service: UserService) -> None:
|
||||
def release_on_logout(self, userservice: UserService) -> None:
|
||||
"""
|
||||
In case of logout, this method will take care of removing the service
|
||||
This is so because on logout, may the userservice returns back to cache if ower service
|
||||
@ -492,15 +497,19 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
|
||||
This method will take care of removing the service if no cache is desired of cache already full (on servicepool)
|
||||
"""
|
||||
stats = self.get_cache_servicepool_stats(user_service.deployed_service)
|
||||
if userservice.deployed_service.service.get_instance().allows_put_back_to_cache() is False:
|
||||
userservice.release()
|
||||
return
|
||||
|
||||
stats = self.get_cache_servicepool_stats(userservice.deployed_service)
|
||||
# Note that only moves to cache L1
|
||||
# Also, we can get values for L2 cache, thats why we check L1 for overflow and needed
|
||||
if stats.has_l1_cache_overflow():
|
||||
user_service.release() # Mark as removable
|
||||
userservice.release() # Mark as removable
|
||||
elif stats.is_l1_cache_growth_required():
|
||||
# Move the clone of the user service to cache, and set our as REMOVED
|
||||
_cache = self.clone_userservice_as_cache(user_service)
|
||||
user_service.set_state(State.REMOVED)
|
||||
self.forced_move_assigned_to_cache_l1(userservice)
|
||||
userservice.release(immediate=True)
|
||||
|
||||
def get_existing_assignation_for_user(
|
||||
self, service_pool: ServicePool, user: User
|
||||
|
@ -252,7 +252,7 @@ class OSManager(Module):
|
||||
This method:
|
||||
- Add log in event to stats
|
||||
- Sets service in use
|
||||
- Invokes userLoggedIn for user service instance
|
||||
- Invokes user_logged_in for user service instance
|
||||
"""
|
||||
unique_id = userservice.unique_id
|
||||
userservice.set_in_use(True)
|
||||
@ -308,7 +308,6 @@ class OSManager(Module):
|
||||
This method:
|
||||
- Add log in event to stats
|
||||
- Sets service in use
|
||||
- Invokes userLoggedIn for user service instance
|
||||
"""
|
||||
with userservice.properties as p:
|
||||
counter = int(typing.cast(str, p.get('logins_counter', 0))) - 1
|
||||
|
@ -269,6 +269,13 @@ class Service(Module):
|
||||
"""
|
||||
return True
|
||||
|
||||
def allows_put_back_to_cache(self) -> bool:
|
||||
"""
|
||||
Returns if this service can be put back to cache. This is used to check if a service can be put back to cache
|
||||
when the user logouts instead of being removed. By default, this method returns False.
|
||||
"""
|
||||
return False
|
||||
|
||||
def unmarshal(self, data: bytes) -> None:
|
||||
# In fact, we will not unmarshal anything here, but setup maxDeployed
|
||||
# if services_limit exists and it is a gui.NumericField
|
||||
|
@ -532,11 +532,14 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
||||
def is_in_maintenance(self) -> bool:
|
||||
return self.deployed_service.is_in_maintenance()
|
||||
|
||||
def release(self) -> None:
|
||||
def release(self, immediate: bool = False) -> None:
|
||||
"""
|
||||
Mark this user deployed service for removal.
|
||||
If from_logout is true, maybe the service can return to cache, else, it will be removed
|
||||
"""
|
||||
if immediate:
|
||||
self.set_state(State.REMOVED)
|
||||
else:
|
||||
self.set_state(State.REMOVABLE)
|
||||
|
||||
def cancel(self) -> None:
|
||||
|
Loading…
Reference in New Issue
Block a user