_reload.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # Copyright 2021-2024 Avaiga Private Limited
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  4. # the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  9. # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  10. # specific language governing permissions and limitations under the License.
  11. import functools
  12. from typing import Dict
  13. from .._manager._manager import _Manager
  14. from ..common._check_dependencies import EnterpriseEditionUtils
  15. from ..common._utils import _load_fct
  16. from ..notification import EventOperation, Notifier, _make_event
  17. class _Reloader:
  18. """The _Reloader singleton class"""
  19. _instance = None
  20. _no_reload_context = False
  21. _managers: Dict[str, _Manager] = {}
  22. def __new__(cls, *args, **kwargs):
  23. if not isinstance(cls._instance, cls):
  24. cls._instance = object.__new__(cls, *args, **kwargs)
  25. cls._managers = cls._build_managers()
  26. return cls._instance
  27. def _reload(self, manager: str, obj):
  28. if self._no_reload_context:
  29. return obj
  30. entity = self._get_manager(manager)._get(obj, obj)
  31. if obj._is_in_context and hasattr(entity, "_properties"):
  32. if obj._properties._pending_changes:
  33. entity._properties._pending_changes = obj._properties._pending_changes
  34. if obj._properties._pending_deletions:
  35. entity._properties._pending_deletions = obj._properties._pending_deletions
  36. entity._properties._entity_owner = obj
  37. return entity
  38. def __enter__(self):
  39. self._no_reload_context = True
  40. return self
  41. def __exit__(self, exc_type, exc_value, exc_traceback):
  42. self._no_reload_context = False
  43. @classmethod
  44. @functools.lru_cache
  45. def _build_managers(cls) -> Dict[str, _Manager]:
  46. from ..cycle._cycle_manager_factory import _CycleManagerFactory
  47. from ..data._data_manager_factory import _DataManagerFactory
  48. from ..job._job_manager_factory import _JobManagerFactory
  49. from ..scenario._scenario_manager_factory import _ScenarioManagerFactory
  50. from ..sequence._sequence_manager_factory import _SequenceManagerFactory
  51. from ..submission._submission_manager_factory import _SubmissionManagerFactory
  52. from ..task._task_manager_factory import _TaskManagerFactory
  53. managers = {
  54. "scenario": _ScenarioManagerFactory._build_manager(),
  55. "sequence": _SequenceManagerFactory._build_manager(),
  56. "data": _DataManagerFactory._build_manager(),
  57. "cycle": _CycleManagerFactory._build_manager(),
  58. "job": _JobManagerFactory._build_manager(),
  59. "task": _TaskManagerFactory._build_manager(),
  60. "submission": _SubmissionManagerFactory._build_manager(),
  61. }
  62. if EnterpriseEditionUtils._using_enterprise():
  63. _build_enterprise_managers = _load_fct(
  64. EnterpriseEditionUtils._TAIPY_ENTERPRISE_CORE_MODULE + "._entity.utils", "_build_enterprise_managers"
  65. )
  66. managers.update(_build_enterprise_managers())
  67. return managers
  68. @classmethod
  69. @functools.lru_cache
  70. def _get_manager(cls, manager: str) -> _Manager:
  71. return cls._managers[manager]
  72. def _self_reload(manager: str):
  73. def __reload(fct):
  74. @functools.wraps(fct)
  75. def _do_reload(self, *args, **kwargs):
  76. self = _Reloader()._reload(manager, self)
  77. return fct(self, *args, **kwargs)
  78. return _do_reload
  79. return __reload
  80. def _self_setter(manager):
  81. def __set_entity(fct):
  82. @functools.wraps(fct)
  83. def _do_set_entity(self, *args, **kwargs):
  84. fct(self, *args, **kwargs)
  85. entity_manager = _Reloader._get_manager(manager)
  86. value = args[0] if len(args) == 1 else args
  87. event = _make_event(
  88. self,
  89. EventOperation.UPDATE,
  90. attribute_name=fct.__name__,
  91. attribute_value=value,
  92. )
  93. if not self._is_in_context:
  94. entity = _Reloader()._reload(manager, self)
  95. fct(entity, *args, **kwargs)
  96. entity_manager._set(entity)
  97. Notifier.publish(event)
  98. else:
  99. self._in_context_attributes_changed_collector.append(event)
  100. return _do_set_entity
  101. return __set_entity