54 lines
1.7 KiB
Python
54 lines
1.7 KiB
Python
from threading import RLock
|
|
from typing import Dict, Optional, Tuple
|
|
|
|
from platypush.entities import Entity
|
|
|
|
|
|
class EntitiesCache:
|
|
"""
|
|
An auxiliary class to model an entities lookup cache with multiple keys.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.by_id: Dict[str, Entity] = {}
|
|
self.by_external_id_and_plugin: Dict[Tuple[str, str], Entity] = {}
|
|
self._lock = RLock()
|
|
|
|
def get(self, entity: Entity) -> Optional[Entity]:
|
|
"""
|
|
Retrieve the cached representation of an entity, if it exists.
|
|
"""
|
|
if entity.id:
|
|
e = self.by_id.get(str(entity.id))
|
|
if e:
|
|
return e
|
|
|
|
if entity.external_id and entity.plugin:
|
|
e = self.by_external_id_and_plugin.get(
|
|
(str(entity.external_id), str(entity.plugin))
|
|
)
|
|
if e:
|
|
return e
|
|
|
|
return None
|
|
|
|
def update(self, *entities: Entity, overwrite=False):
|
|
"""
|
|
Update the cache with a list of new entities.
|
|
"""
|
|
with self._lock:
|
|
for entity in entities:
|
|
if not overwrite:
|
|
existing_entity = self.by_id.get(str(entity.id))
|
|
if existing_entity:
|
|
for k, v in existing_entity.to_json().items():
|
|
if getattr(entity, k, None) is None:
|
|
setattr(entity, k, v)
|
|
|
|
if entity.id:
|
|
self.by_id[str(entity.id)] = entity
|
|
if entity.external_id and entity.plugin:
|
|
self.by_external_id_and_plugin[
|
|
(str(entity.external_id), str(entity.plugin))
|
|
] = entity
|