You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
4.3 KiB
125 lines
4.3 KiB
from django.conf import settings
|
|
from django.apps import apps
|
|
from django.contrib.auth import get_user_model
|
|
|
|
import threading
|
|
import logging
|
|
import importlib
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class ModelRegistry:
|
|
def __init__(self):
|
|
self._registry = {}
|
|
|
|
def load_sync_apps(self):
|
|
base_model = get_abstract_model_class('BaseModel')
|
|
sync_apps = getattr(settings, 'SYNC_APPS', {})
|
|
for app_label, config in sync_apps.items():
|
|
app_models = apps.get_app_config(app_label).get_models()
|
|
for model in app_models:
|
|
if hasattr(model, '_meta') and not model._meta.abstract:
|
|
if issubclass(model, base_model) or model == get_user_model():
|
|
model_name = model.__name__
|
|
if self.should_sync_model(model_name, config):
|
|
self.register(model)
|
|
|
|
def should_sync_model(self, model_name, config):
|
|
if 'exclude' in config and model_name in config['exclude']:
|
|
return False
|
|
if 'models' in config and config['models']:
|
|
return model_name in config['models']
|
|
return True
|
|
|
|
def register(self, model):
|
|
self._registry[model.__name__] = model
|
|
|
|
def get_model(self, model_name):
|
|
if not self._registry:
|
|
self.load_sync_apps()
|
|
return self._registry.get(model_name)
|
|
|
|
# Global instance
|
|
model_registry = ModelRegistry()
|
|
|
|
def get_abstract_model_class(model_name):
|
|
module = importlib.import_module('sync.models')
|
|
return getattr(module, model_name)
|
|
|
|
class DeviceRegistry:
|
|
"""Thread-safe registry to track device IDs associated with model instances."""
|
|
|
|
def __init__(self):
|
|
self._registry = {}
|
|
self._lock = threading.RLock()
|
|
|
|
def count(self):
|
|
"""Return the number of items in the registry."""
|
|
with self._lock:
|
|
return len(self._registry)
|
|
|
|
def register(self, instance_id, device_id):
|
|
"""Register a device_id for a model instance ID."""
|
|
with self._lock:
|
|
self._registry[str(instance_id)] = device_id
|
|
|
|
def get_device_id(self, instance_id):
|
|
"""Get the device_id for a model instance ID."""
|
|
with self._lock:
|
|
return self._registry.get(str(instance_id))
|
|
|
|
def unregister(self, instance_id):
|
|
"""Remove an instance from the registry."""
|
|
with self._lock:
|
|
if instance_id in self._registry:
|
|
del self._registry[instance_id]
|
|
|
|
# Global instance
|
|
device_registry = DeviceRegistry()
|
|
|
|
class RelatedUsersRegistry:
|
|
"""Thread-safe registry to track device IDs associated with model instances."""
|
|
|
|
def __init__(self):
|
|
self._registry = {}
|
|
self._lock = threading.RLock()
|
|
|
|
def count(self):
|
|
"""Return the number of items in the registry."""
|
|
with self._lock:
|
|
return len(self._registry)
|
|
|
|
def register(self, instance_id, users):
|
|
"""Register a device_id for a model instance ID."""
|
|
# logger.info(f'USER REGISTRY register {instance_id} : {users}')
|
|
with self._lock:
|
|
instance_id_str = str(instance_id)
|
|
if instance_id_str in self._registry:
|
|
existing_users = self._registry[instance_id_str]
|
|
self._registry[instance_id_str] = existing_users.union(users)
|
|
else:
|
|
self._registry[instance_id_str] = set(users) # we convert to set because transmitted query_set are emptying themselves
|
|
|
|
def get_users(self, instance_id):
|
|
"""Get the device_id for a model instance ID."""
|
|
with self._lock:
|
|
instance_id_str = str(instance_id)
|
|
if instance_id_str in self._registry:
|
|
# logger.info(f'###### get_users exists ! {instance_id}')
|
|
return self._registry[instance_id_str]
|
|
else:
|
|
# logger.info(f'####### get_users {instance_id} not referenced !')
|
|
return {}
|
|
|
|
# return self._registry.get(instance_id_str)
|
|
|
|
def unregister(self, instance_id):
|
|
"""Remove an instance from the registry."""
|
|
# logger.info(f'USER REGISTRY unregister {instance_id}')
|
|
with self._lock:
|
|
instance_id_str = str(instance_id)
|
|
if instance_id_str in self._registry:
|
|
del self._registry[instance_id_str]
|
|
|
|
# Global instance
|
|
related_users_registry = RelatedUsersRegistry()
|
|
|