mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-05 09:17:54 +03:00
adding __slots__ to optimize a bit code
This commit is contained in:
parent
a6c6bca2fd
commit
552ba3796b
@ -47,6 +47,7 @@ class Environment:
|
|||||||
not stored with main module data.
|
not stored with main module data.
|
||||||
The environment is composed of a "cache" and a "storage". First are volatile data, while second are persistent data.
|
The environment is composed of a "cache" and a "storage". First are volatile data, while second are persistent data.
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ['_key', '_cache', '_storage', '_idGenerators']
|
||||||
|
|
||||||
_key: str
|
_key: str
|
||||||
_cache: Cache
|
_cache: Cache
|
||||||
@ -173,6 +174,9 @@ class Environmentable:
|
|||||||
"""
|
"""
|
||||||
This is a base class provided for all objects that have an environment associated. These are mainly modules
|
This is a base class provided for all objects that have an environment associated. These are mainly modules
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ['_env']
|
||||||
|
|
||||||
|
_env: Environment
|
||||||
|
|
||||||
def __init__(self, environment: Environment):
|
def __init__(self, environment: Environment):
|
||||||
"""
|
"""
|
||||||
|
@ -42,6 +42,7 @@ class DelayedTask(Environmentable):
|
|||||||
This class represents a single delayed task object.
|
This class represents a single delayed task object.
|
||||||
This is an object that represents an execution to be done "later"
|
This is an object that represents an execution to be done "later"
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
|
@ -44,6 +44,7 @@ from django.db.models import Q
|
|||||||
from uds.models import DelayedTask as DBDelayedTask
|
from uds.models import DelayedTask as DBDelayedTask
|
||||||
from uds.models import getSqlDatetime
|
from uds.models import getSqlDatetime
|
||||||
from uds.core.environment import Environment
|
from uds.core.environment import Environment
|
||||||
|
from uds.core.util import singleton
|
||||||
|
|
||||||
from .delayed_task import DelayedTask
|
from .delayed_task import DelayedTask
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ class DelayedTaskThread(threading.Thread):
|
|||||||
"""
|
"""
|
||||||
Class responsible of executing a delayed task in its own thread
|
Class responsible of executing a delayed task in its own thread
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ('_taskInstance',)
|
||||||
|
|
||||||
_taskInstance: DelayedTask
|
_taskInstance: DelayedTask
|
||||||
|
|
||||||
@ -70,29 +72,27 @@ class DelayedTaskThread(threading.Thread):
|
|||||||
connections['default'].close()
|
connections['default'].close()
|
||||||
|
|
||||||
|
|
||||||
class DelayedTaskRunner:
|
class DelayedTaskRunner(metaclass=singleton.Singleton):
|
||||||
"""
|
"""
|
||||||
Delayed task runner class
|
Delayed task runner class
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
granularity: int = 2 # we check for delayed tasks every "granularity" seconds
|
granularity: typing.ClassVar[int] = 2 # we check for delayed tasks every "granularity" seconds
|
||||||
|
_hostname: typing.ClassVar[str] # "Our" hostname
|
||||||
# to keep singleton DelayedTaskRunner
|
_keepRunning: typing.ClassVar[bool] # If we should keep it running
|
||||||
_runner: typing.ClassVar[typing.Optional['DelayedTaskRunner']] = None
|
|
||||||
_hostname: str
|
|
||||||
_keepRunning: bool
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._hostname = gethostname()
|
|
||||||
self._keepRunning = True
|
|
||||||
logger.debug("Initializing delayed task runner for host %s", self._hostname)
|
logger.debug("Initializing delayed task runner for host %s", self._hostname)
|
||||||
|
DelayedTaskRunner._hostname = gethostname()
|
||||||
|
DelayedTaskRunner._keepRunning = True
|
||||||
|
|
||||||
def notifyTermination(self) -> None:
|
def notifyTermination(self) -> None:
|
||||||
"""
|
"""
|
||||||
Invoke this whenever you want to terminate the delayed task runner thread
|
Invoke this whenever you want to terminate the delayed task runner thread
|
||||||
It will mark the thread to "stop" ASAP
|
It will mark the thread to "stop" ASAP
|
||||||
"""
|
"""
|
||||||
self._keepRunning = False
|
DelayedTaskRunner._keepRunning = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def runner() -> 'DelayedTaskRunner':
|
def runner() -> 'DelayedTaskRunner':
|
||||||
@ -101,9 +101,7 @@ class DelayedTaskRunner:
|
|||||||
There is only one instance of DelayedTaksRunner, but its "run" method is executed on
|
There is only one instance of DelayedTaksRunner, but its "run" method is executed on
|
||||||
many thread (depending on configuration). They all share common Instance data
|
many thread (depending on configuration). They all share common Instance data
|
||||||
"""
|
"""
|
||||||
if DelayedTaskRunner._runner is None:
|
return DelayedTaskRunner()
|
||||||
DelayedTaskRunner._runner = DelayedTaskRunner()
|
|
||||||
return DelayedTaskRunner._runner
|
|
||||||
|
|
||||||
def executeOneDelayedTask(self) -> None:
|
def executeOneDelayedTask(self) -> None:
|
||||||
now = getSqlDatetime()
|
now = getSqlDatetime()
|
||||||
@ -142,7 +140,7 @@ class DelayedTaskRunner:
|
|||||||
taskInstance.env = Environment.getEnvForType(taskInstance.__class__)
|
taskInstance.env = Environment.getEnvForType(taskInstance.__class__)
|
||||||
DelayedTaskThread(taskInstance).start()
|
DelayedTaskThread(taskInstance).start()
|
||||||
|
|
||||||
def __insert(self, instance: DelayedTask, delay: int, tag: str) -> None:
|
def _insert(self, instance: DelayedTask, delay: int, tag: str) -> None:
|
||||||
now = getSqlDatetime()
|
now = getSqlDatetime()
|
||||||
exec_time = now + timedelta(seconds=delay)
|
exec_time = now + timedelta(seconds=delay)
|
||||||
cls = instance.__class__
|
cls = instance.__class__
|
||||||
@ -170,7 +168,7 @@ class DelayedTaskRunner:
|
|||||||
while retries > 0:
|
while retries > 0:
|
||||||
retries -= 1
|
retries -= 1
|
||||||
try:
|
try:
|
||||||
self.__insert(instance, delay, tag)
|
self._insert(instance, delay, tag)
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info('Exception inserting a delayed task %s: %s', e.__class__, e)
|
logger.info('Exception inserting a delayed task %s: %s', e.__class__, e)
|
||||||
@ -210,7 +208,7 @@ class DelayedTaskRunner:
|
|||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
logger.debug("At loop")
|
logger.debug("At loop")
|
||||||
while self._keepRunning:
|
while DelayedTaskRunner._keepRunning:
|
||||||
try:
|
try:
|
||||||
time.sleep(self.granularity)
|
time.sleep(self.granularity)
|
||||||
self.executeOneDelayedTask()
|
self.executeOneDelayedTask()
|
||||||
|
@ -39,15 +39,16 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Job(Environmentable):
|
class Job(Environmentable):
|
||||||
|
__slots__ = ('frequency',)
|
||||||
# Default frecuency, once a day. Remenber that precision will be based on "granurality" of Scheduler
|
# Default frecuency, once a day. Remenber that precision will be based on "granurality" of Scheduler
|
||||||
# If a job is used for delayed execution, this attribute is in fact ignored
|
# If a job is used for delayed execution, this attribute is in fact ignored
|
||||||
frecuency: int = (
|
frecuency: typing.ClassVar[int] = (
|
||||||
24 * 3600 + 3
|
24 * 3600 + 3
|
||||||
) # Defaults to a big one, and i know frecuency is written as frequency, but this is an "historical mistake" :)
|
) # Defaults to a big one, and i know frecuency is written as frequency, but this is an "historical mistake" :)
|
||||||
frecuency_cfg: typing.Optional[
|
frecuency_cfg: typing.ClassVar[
|
||||||
Config.Value
|
typing.Optional[Config.Value]
|
||||||
] = None # If we use a configuration variable from DB, we need to update the frecuency asap, but not before app is ready
|
] = None # If we use a configuration variable from DB, we need to update the frecuency asap, but not before app is ready
|
||||||
friendly_name = 'Unknown'
|
friendly_name: typing.ClassVar[str] = 'Unknown'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup(cls: typing.Type['Job']) -> None:
|
def setup(cls: typing.Type['Job']) -> None:
|
||||||
|
@ -68,10 +68,15 @@ class DelayedTaskThread(BaseThread):
|
|||||||
|
|
||||||
|
|
||||||
class TaskManager(metaclass=singleton.Singleton):
|
class TaskManager(metaclass=singleton.Singleton):
|
||||||
keepRunning: bool = True
|
|
||||||
threads: typing.List[BaseThread] = []
|
__slots__ = ('threads', 'keepRunning')
|
||||||
|
|
||||||
|
keepRunning: bool
|
||||||
|
threads: typing.List[BaseThread]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.keepRunning = True
|
||||||
|
self.threads = []
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -97,6 +97,7 @@ class Module(UserInterface, Environmentable, Serializable):
|
|||||||
Environmentable is a base class that provides utility method to access a separate Environment for every single
|
Environmentable is a base class that provides utility method to access a separate Environment for every single
|
||||||
module.
|
module.
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ['_uuid']
|
||||||
# Import variable indicating this module is a base class not a real module
|
# Import variable indicating this module is a base class not a real module
|
||||||
# Note that Module is not a real module, but a base class for all modules so isBase is not used on this class
|
# Note that Module is not a real module, but a base class for all modules so isBase is not used on this class
|
||||||
isBase: typing.ClassVar[bool] = False
|
isBase: typing.ClassVar[bool] = False
|
||||||
|
@ -43,6 +43,7 @@ class Serializable:
|
|||||||
- Initialize the object with default values
|
- Initialize the object with default values
|
||||||
- Read values from seralized data
|
- Read values from seralized data
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
@ -53,14 +53,16 @@ ONE_DAY = 3600 * 24
|
|||||||
|
|
||||||
|
|
||||||
class CalendarChecker:
|
class CalendarChecker:
|
||||||
|
__slots__ = ('calendar',)
|
||||||
|
|
||||||
calendar: Calendar
|
calendar: Calendar
|
||||||
|
|
||||||
# For performance checking
|
# For performance checking
|
||||||
updates: int = 0
|
updates: typing.ClassVar[int] = 0
|
||||||
cache_hit: int = 0
|
cache_hit: typing.ClassVar[int] = 0
|
||||||
hits: int = 0
|
hits: typing.ClassVar[int] = 0
|
||||||
|
|
||||||
cache = Cache('calChecker')
|
cache: typing.ClassVar[Cache] = Cache('calChecker')
|
||||||
|
|
||||||
def __init__(self, calendar: Calendar) -> None:
|
def __init__(self, calendar: Calendar) -> None:
|
||||||
self.calendar = calendar
|
self.calendar = calendar
|
||||||
|
@ -44,6 +44,7 @@ class RedirectMiddleware:
|
|||||||
|
|
||||||
Some paths will not be redirected, to avoid problems, but they are advised to use SSL (this is for backwards compat)
|
Some paths will not be redirected, to avoid problems, but they are advised to use SSL (this is for backwards compat)
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ('get_response',)
|
||||||
|
|
||||||
NO_REDIRECT: typing.ClassVar[typing.List[str]] = [
|
NO_REDIRECT: typing.ClassVar[typing.List[str]] = [
|
||||||
'rest',
|
'rest',
|
||||||
|
@ -51,6 +51,8 @@ CHECK_SECONDS = 3600 * 24 # Once a day is more than enough
|
|||||||
|
|
||||||
|
|
||||||
class GlobalRequestMiddleware:
|
class GlobalRequestMiddleware:
|
||||||
|
__slots__ = ('_get_response',)
|
||||||
|
|
||||||
lastCheck: typing.ClassVar[datetime.datetime] = datetime.datetime.now()
|
lastCheck: typing.ClassVar[datetime.datetime] = datetime.datetime.now()
|
||||||
|
|
||||||
def __init__(self, get_response: typing.Callable[[HttpRequest], HttpResponse]):
|
def __init__(self, get_response: typing.Callable[[HttpRequest], HttpResponse]):
|
||||||
|
@ -46,6 +46,7 @@ class UDSSecurityMiddleware:
|
|||||||
'''
|
'''
|
||||||
This class contains all the security checks done by UDS in order to add some extra protection.
|
This class contains all the security checks done by UDS in order to add some extra protection.
|
||||||
'''
|
'''
|
||||||
|
__slots__ = ('get_response',)
|
||||||
|
|
||||||
get_response: typing.Any # typing.Callable[['HttpRequest'], 'HttpResponse']
|
get_response: typing.Any # typing.Callable[['HttpRequest'], 'HttpResponse']
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ class XUACompatibleMiddleware:
|
|||||||
This header tells to Internet Explorer to render page with latest
|
This header tells to Internet Explorer to render page with latest
|
||||||
possible version or to use chrome frame if it is installed.
|
possible version or to use chrome frame if it is installed.
|
||||||
"""
|
"""
|
||||||
|
__slots__ = ('get_response',)
|
||||||
|
|
||||||
def __init__(self, get_response):
|
def __init__(self, get_response):
|
||||||
self.get_response = get_response
|
self.get_response = get_response
|
||||||
|
@ -8,14 +8,14 @@ class Singleton(type):
|
|||||||
class MyClass(metaclass=Singleton):
|
class MyClass(metaclass=Singleton):
|
||||||
...
|
...
|
||||||
'''
|
'''
|
||||||
__instance: typing.Optional[typing.Any]
|
_instance: typing.Optional[typing.Any]
|
||||||
|
|
||||||
# We use __init__ so we customise the created class from this metaclass
|
# We use __init__ so we customise the created class from this metaclass
|
||||||
def __init__(self, *args, **kwargs) -> None:
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
self.__instance = None
|
self._instance = None
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs) -> typing.Any:
|
def __call__(self, *args, **kwargs) -> typing.Any:
|
||||||
if self.__instance is None:
|
if self._instance is None:
|
||||||
self.__instance = super().__call__(*args, **kwargs)
|
self._instance = super().__call__(*args, **kwargs)
|
||||||
return self.__instance
|
return self._instance
|
||||||
|
@ -38,6 +38,8 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class UniqueGIDGenerator(UniqueIDGenerator):
|
class UniqueGIDGenerator(UniqueIDGenerator):
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
def __init__(self, owner, baseName=None):
|
def __init__(self, owner, baseName=None):
|
||||||
super().__init__('id', owner, baseName)
|
super().__init__('id', owner, baseName)
|
||||||
|
|
||||||
|
@ -53,7 +53,11 @@ class CreateNewIdException(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class UniqueIDGenerator:
|
class UniqueIDGenerator:
|
||||||
|
__slots__ = ('_owner', '_baseName')
|
||||||
|
|
||||||
|
# owner is the owner of the UniqueID
|
||||||
_owner: str
|
_owner: str
|
||||||
|
# base name for filtering unique ids. (I.e. "mac", "ip", "ipv6" ....)
|
||||||
_baseName: str
|
_baseName: str
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -39,6 +39,8 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class UniqueMacGenerator(UniqueIDGenerator):
|
class UniqueMacGenerator(UniqueIDGenerator):
|
||||||
|
__slots__ = ('_macRange',)
|
||||||
|
|
||||||
def __init__(self, owner: str) -> None:
|
def __init__(self, owner: str) -> None:
|
||||||
super().__init__('mac', owner, '\tmac')
|
super().__init__('mac', owner, '\tmac')
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# noinspection PyMethodOverriding
|
# noinspection PyMethodOverriding
|
||||||
class UniqueNameGenerator(UniqueIDGenerator):
|
class UniqueNameGenerator(UniqueIDGenerator):
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
def __init__(self, owner):
|
def __init__(self, owner):
|
||||||
super().__init__('name', owner)
|
super().__init__('name', owner)
|
||||||
|
|
||||||
@ -53,7 +55,7 @@ class UniqueNameGenerator(UniqueIDGenerator):
|
|||||||
maxVal = 10 ** length - 1
|
maxVal = 10 ** length - 1
|
||||||
return self.__toName(super().get(minVal, maxVal), length)
|
return self.__toName(super().get(minVal, maxVal), length)
|
||||||
|
|
||||||
def transfer(self, baseName: str, name: str, toUNGen: 'UniqueNameGenerator'): # type: ignore # pylint: disable=arguments-differ
|
def transfer(self, baseName: str, name: str, toUNGen: 'UniqueNameGenerator') -> None: # type: ignore
|
||||||
self.setBaseName(baseName)
|
self.setBaseName(baseName)
|
||||||
super().transfer(int(name[len(self._baseName) :]), toUNGen)
|
super().transfer(int(name[len(self._baseName) :]), toUNGen)
|
||||||
|
|
||||||
|
@ -170,3 +170,21 @@ def validateMacRange(macRange: str) -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
return macRange
|
return macRange
|
||||||
|
|
||||||
|
def validateEmail(email: str) -> str:
|
||||||
|
"""
|
||||||
|
Validates that an email is valid
|
||||||
|
:param email: email to validate
|
||||||
|
:return: Raises Module.Validation exception if is invalid, else return the value "fixed"
|
||||||
|
"""
|
||||||
|
if len(email) > 254:
|
||||||
|
raise Module.ValidationException(
|
||||||
|
_('Email address is too long')
|
||||||
|
)
|
||||||
|
|
||||||
|
if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
|
||||||
|
raise Module.ValidationException(
|
||||||
|
_('Email address is not valid')
|
||||||
|
)
|
||||||
|
|
||||||
|
return email
|
||||||
|
Loading…
Reference in New Issue
Block a user