mirror of
https://github.com/dkmstr/openuds.git
synced 2025-03-20 06:50:23 +03:00
Better singleton pattern (more reusable)
This commit is contained in:
parent
8e3d90e7f3
commit
54f7fd21dc
@ -45,36 +45,36 @@ if typing.TYPE_CHECKING:
|
||||
|
||||
|
||||
def cryptoManager() -> 'CryptoManager':
|
||||
from .crypto import CryptoManager # pylint: disable=redefined-outer-name
|
||||
from .crypto import CryptoManager
|
||||
|
||||
return CryptoManager.manager()
|
||||
|
||||
|
||||
def taskManager() -> typing.Type['TaskManager']:
|
||||
from .task import TaskManager # pylint: disable=redefined-outer-name
|
||||
def taskManager() -> 'TaskManager':
|
||||
from .task import TaskManager
|
||||
|
||||
return TaskManager
|
||||
return TaskManager.manager()
|
||||
|
||||
|
||||
def downloadsManager() -> 'DownloadsManager':
|
||||
from .downloads import DownloadsManager # pylint: disable=redefined-outer-name
|
||||
from .downloads import DownloadsManager
|
||||
|
||||
return DownloadsManager.manager()
|
||||
|
||||
|
||||
def logManager() -> 'LogManager':
|
||||
from .log import LogManager # pylint: disable=redefined-outer-name
|
||||
from .log import LogManager
|
||||
|
||||
return LogManager.manager()
|
||||
|
||||
|
||||
def userServiceManager() -> 'UserServiceManager':
|
||||
from .user_service import UserServiceManager # pylint: disable=redefined-outer-name
|
||||
from .user_service import UserServiceManager
|
||||
|
||||
return UserServiceManager.manager()
|
||||
|
||||
|
||||
def publicationManager() -> 'PublicationManager':
|
||||
from .publication import PublicationManager # pylint: disable=redefined-outer-name
|
||||
from .publication import PublicationManager
|
||||
|
||||
return PublicationManager.manager()
|
||||
|
@ -49,6 +49,8 @@ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from uds.core.util import singleton
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
@ -58,9 +60,7 @@ if typing.TYPE_CHECKING:
|
||||
from cryptography.hazmat.primitives.asymmetric.dh import DHPrivateKey
|
||||
|
||||
|
||||
class CryptoManager:
|
||||
instance = None
|
||||
|
||||
class CryptoManager(metaclass=singleton.Singleton):
|
||||
def __init__(self):
|
||||
self._rsa = serialization.load_pem_private_key(
|
||||
settings.RSA_KEY.encode(), password=None, backend=default_backend()
|
||||
@ -87,9 +87,7 @@ class CryptoManager:
|
||||
|
||||
@staticmethod
|
||||
def manager() -> 'CryptoManager':
|
||||
if CryptoManager.instance is None:
|
||||
CryptoManager.instance = CryptoManager()
|
||||
return CryptoManager.instance
|
||||
return CryptoManager() # Singleton pattern will return always the same instance
|
||||
|
||||
def encrypt(self, value: str) -> str:
|
||||
return codecs.encode(
|
||||
@ -117,7 +115,7 @@ class CryptoManager:
|
||||
label=None,
|
||||
),
|
||||
)
|
||||
except Exception: # If fails, try old method
|
||||
except Exception: # Old method is not supported
|
||||
logger.exception('Decripting: %s', value)
|
||||
return 'decript error'
|
||||
# logger.debug('Decripted: %s %s', data, decrypted)
|
||||
|
@ -39,12 +39,12 @@ from wsgiref.util import FileWrapper
|
||||
from django.http import HttpResponse, Http404
|
||||
|
||||
from uds.core.managers import cryptoManager
|
||||
|
||||
from uds.core.util import singleton
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DownloadsManager:
|
||||
class DownloadsManager(metaclass=singleton.Singleton):
|
||||
"""
|
||||
Manager so connectors can register their own downloadables
|
||||
For registering, use at __init__.py of the conecto something like this:
|
||||
@ -56,17 +56,16 @@ class DownloadsManager:
|
||||
'application/x-msdos-program')
|
||||
"""
|
||||
|
||||
_manager: typing.Optional['DownloadsManager'] = None
|
||||
_downloadables: typing.Dict[str, typing.Dict[str, str]] = {}
|
||||
|
||||
def __init__(self):
|
||||
self._downloadables = {}
|
||||
|
||||
@staticmethod
|
||||
def manager():
|
||||
if DownloadsManager._manager is None:
|
||||
DownloadsManager._manager = DownloadsManager()
|
||||
return DownloadsManager._manager
|
||||
def manager() -> 'DownloadsManager':
|
||||
return (
|
||||
DownloadsManager()
|
||||
) # Singleton pattern will return always the same instance
|
||||
|
||||
def registerDownloadable(
|
||||
self, name: str, comment: str, path: str, mime: str = 'application/octet-stream'
|
||||
|
@ -36,6 +36,7 @@ import typing
|
||||
from uds import models
|
||||
|
||||
from uds.core.util.config import GlobalConfig
|
||||
from uds.core.util import singleton
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
@ -72,21 +73,17 @@ transDict: typing.Dict[typing.Type['Model'], int] = {
|
||||
}
|
||||
|
||||
|
||||
class LogManager:
|
||||
class LogManager(metaclass=singleton.Singleton):
|
||||
"""
|
||||
Manager for logging (at database) events
|
||||
"""
|
||||
|
||||
_manager: typing.Optional['LogManager'] = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def manager() -> 'LogManager':
|
||||
if not LogManager._manager:
|
||||
LogManager._manager = LogManager()
|
||||
return LogManager._manager
|
||||
return LogManager() # Singleton pattern will return always the same instance
|
||||
|
||||
def __log(
|
||||
self,
|
||||
@ -204,7 +201,9 @@ class LogManager:
|
||||
self.__clearLogs(owner_type, wichObject.id) # type: ignore
|
||||
else:
|
||||
logger.debug(
|
||||
'Requested clearLogs for a type of object not covered: %s: %s', type(wichObject), wichObject
|
||||
'Requested clearLogs for a type of object not covered: %s: %s',
|
||||
type(wichObject),
|
||||
wichObject,
|
||||
)
|
||||
for line in traceback.format_stack(limit=5):
|
||||
logger.debug('>> %s', line)
|
||||
|
@ -45,6 +45,8 @@ from uds.core.util import log
|
||||
|
||||
from uds.models import ServicePoolPublication, getSqlDatetime, ServicePool
|
||||
|
||||
from uds.core.util import singleton
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds.core import services
|
||||
|
||||
@ -255,13 +257,11 @@ class PublicationFinishChecker(DelayedTask):
|
||||
)
|
||||
|
||||
|
||||
class PublicationManager:
|
||||
class PublicationManager(metaclass=singleton.Singleton):
|
||||
"""
|
||||
Manager responsible of controlling publications
|
||||
"""
|
||||
|
||||
_manager: typing.Optional['PublicationManager'] = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@ -270,9 +270,9 @@ class PublicationManager:
|
||||
"""
|
||||
Returns the singleton to this manager
|
||||
"""
|
||||
if not PublicationManager._manager:
|
||||
PublicationManager._manager = PublicationManager()
|
||||
return PublicationManager._manager
|
||||
return (
|
||||
PublicationManager()
|
||||
) # Singleton pattern will return always the same instance
|
||||
|
||||
def publish(
|
||||
self, servicePool: ServicePool, changeLog: typing.Optional[str] = None
|
||||
|
@ -35,6 +35,7 @@ import logging
|
||||
import typing
|
||||
|
||||
from uds.core.util.config import GlobalConfig
|
||||
from uds.core.util import singleton
|
||||
from uds.models import StatsCounters
|
||||
from uds.models import getSqlDatetime, getSqlDatetimeAsUnix
|
||||
from uds.models import StatsEvents
|
||||
@ -53,7 +54,7 @@ REVERSE_FLDS_EQUIV: typing.Mapping[str, str] = {
|
||||
}
|
||||
|
||||
|
||||
class StatsManager:
|
||||
class StatsManager(metaclass=singleton.Singleton):
|
||||
"""
|
||||
Manager for statistics, so we can provide usefull info about platform usage
|
||||
|
||||
@ -62,16 +63,12 @@ class StatsManager:
|
||||
are assigned, are in use, in cache, etc...
|
||||
"""
|
||||
|
||||
_manager: typing.Optional['StatsManager'] = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def manager():
|
||||
if not StatsManager._manager:
|
||||
StatsManager._manager = StatsManager()
|
||||
return StatsManager._manager
|
||||
def manager() -> 'StatsManager':
|
||||
return StatsManager() # Singleton pattern will return always the same instance
|
||||
|
||||
def __doCleanup(self, model):
|
||||
minTime = time.mktime(
|
||||
|
@ -41,6 +41,7 @@ from uds.core.jobs.scheduler import Scheduler
|
||||
from uds.core.jobs.delayed_task_runner import DelayedTaskRunner
|
||||
from uds.core import jobs
|
||||
from uds.core.util.config import GlobalConfig
|
||||
from uds.core.util import singleton
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -66,9 +67,16 @@ class DelayedTaskThread(BaseThread):
|
||||
DelayedTaskRunner.runner().notifyTermination()
|
||||
|
||||
|
||||
class TaskManager:
|
||||
class TaskManager(metaclass=singleton.Singleton):
|
||||
keepRunning: bool = True
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def manager() -> 'TaskManager':
|
||||
return TaskManager()
|
||||
|
||||
@staticmethod
|
||||
def sigTerm(sigNum, frame):
|
||||
"""
|
||||
@ -80,24 +88,20 @@ class TaskManager:
|
||||
Take a look at killTaskManager.sh :-)
|
||||
"""
|
||||
logger.info("Caught term signal, finishing task manager")
|
||||
TaskManager.keepRunning = False
|
||||
TaskManager.manager().keepRunning = False
|
||||
|
||||
@staticmethod
|
||||
def registerJob(jobType: typing.Type[jobs.Job]) -> None:
|
||||
def registerJob(self, jobType: typing.Type[jobs.Job]) -> None:
|
||||
jobName = jobType.friendly_name
|
||||
jobs.factory().insert(jobName, jobType)
|
||||
|
||||
@staticmethod
|
||||
def registerScheduledTasks() -> None:
|
||||
|
||||
def registerScheduledTasks(self) -> None:
|
||||
logger.info("Registering sheduled tasks")
|
||||
|
||||
# Simply import this to make workers "auto import themself"
|
||||
from uds.core import workers # @UnusedImport pylint: disable=unused-import
|
||||
|
||||
@staticmethod
|
||||
def run() -> None:
|
||||
TaskManager.keepRunning = True
|
||||
def run(self) -> None:
|
||||
self.keepRunning = True
|
||||
|
||||
# Don't know why, but with django 1.8, must "reset" connections so them do not fail on first access...
|
||||
# Is simmilar to https://code.djangoproject.com/ticket/21597#comment:29
|
||||
@ -106,7 +110,7 @@ class TaskManager:
|
||||
# Releases owned schedules so anyone can access them...
|
||||
Scheduler.releaseOwnShedules()
|
||||
|
||||
TaskManager.registerScheduledTasks()
|
||||
self.registerScheduledTasks()
|
||||
|
||||
noSchedulers: int = GlobalConfig.SCHEDULER_THREADS.getInt()
|
||||
noDelayedTasks: int = GlobalConfig.DELAYED_TASKS_THREADS.getInt()
|
||||
|
@ -38,6 +38,8 @@ import typing
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
|
||||
from uds.core.util import singleton
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds.models import User
|
||||
|
||||
@ -45,8 +47,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# UserPrefs is DEPRECATED
|
||||
# Currently not used anywhere
|
||||
class UserPrefsManager:
|
||||
_manager: typing.Optional['UserPrefsManager'] = None
|
||||
class UserPrefsManager(metaclass=singleton.Singleton):
|
||||
_prefs: typing.Dict[str, typing.Dict]
|
||||
|
||||
def __init__(self):
|
||||
@ -54,9 +55,7 @@ class UserPrefsManager:
|
||||
|
||||
@staticmethod
|
||||
def manager() -> 'UserPrefsManager':
|
||||
if UserPrefsManager._manager is None:
|
||||
UserPrefsManager._manager = UserPrefsManager()
|
||||
return UserPrefsManager._manager
|
||||
return UserPrefsManager()
|
||||
|
||||
def __nameFor(self, module, name):
|
||||
return module + "_" + name
|
||||
|
@ -58,6 +58,7 @@ from uds.models import (
|
||||
)
|
||||
from uds.models.meta_pool import MetaPoolMember
|
||||
from uds.core import services, transports
|
||||
from uds.core.util import singleton
|
||||
from uds.core.util.stats import events
|
||||
|
||||
from .userservice import comms
|
||||
@ -67,17 +68,13 @@ logger = logging.getLogger(__name__)
|
||||
traceLogger = logging.getLogger('traceLog')
|
||||
|
||||
|
||||
class UserServiceManager:
|
||||
_manager: typing.Optional['UserServiceManager'] = None
|
||||
|
||||
class UserServiceManager(metaclass=singleton.Singleton):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def manager() -> 'UserServiceManager':
|
||||
if not UserServiceManager._manager:
|
||||
UserServiceManager._manager = UserServiceManager()
|
||||
return UserServiceManager._manager
|
||||
return UserServiceManager() # Singleton pattern will return always the same instance
|
||||
|
||||
@staticmethod
|
||||
def getCacheStateFilter(level: int) -> Q:
|
||||
|
10
server/src/uds/core/util/singleton.py
Normal file
10
server/src/uds/core/util/singleton.py
Normal file
@ -0,0 +1,10 @@
|
||||
# Metaclass for singleton pattern
|
||||
class Singleton(type):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.__instance = None
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if self.__instance is None:
|
||||
self.__instance = super().__call__(*args, **kwargs)
|
||||
return self.__instance
|
Loading…
x
Reference in New Issue
Block a user