131 lines
4.9 KiB
Python
131 lines
4.9 KiB
Python
from dataclasses import dataclass
|
|
from typing import List
|
|
|
|
from cache.Cache import Cache
|
|
from core.builtin_concepts import BuiltinConcepts
|
|
from core.global_symbols import NotFound
|
|
from core.sheerka.services.sheerka_service import ServiceObj, BaseService
|
|
|
|
|
|
@dataclass
|
|
class Variable(ServiceObj):
|
|
"""
|
|
Variable to store
|
|
"""
|
|
who: str # who is the modifier
|
|
key: str # key of the variable
|
|
value: object # value
|
|
parents: List[str] # previous references of the variable (Note that there should be only one parent)
|
|
|
|
def get_key(self):
|
|
return f"{self.who}|{self.key}"
|
|
|
|
def __str__(self):
|
|
return f"({self.who}){self.key}={self.value}"
|
|
|
|
|
|
@dataclass
|
|
class InternalObj:
|
|
obj: object
|
|
|
|
def __deepcopy__(self, memodict={}):
|
|
return self
|
|
|
|
def __copy__(self):
|
|
return self
|
|
|
|
|
|
class SheerkaVariableManager(BaseService):
|
|
NAME = "VariableManager"
|
|
VARIABLES_ENTRY = "VariableManager:Variables" # entry for variables which will be copied in sdp
|
|
INTERNAL_VARIABLES_ENTRY = "VariableManager:InternalVariables" # internal to current process (can store lambda)
|
|
|
|
def __init__(self, sheerka):
|
|
super().__init__(sheerka)
|
|
self.bound_variables = {
|
|
self.sheerka.name: {"enable_process_return_values", "save_execution_context"}
|
|
}
|
|
|
|
def initialize(self):
|
|
self.sheerka.bind_service_method(self.record_var, True, visible=False)
|
|
self.sheerka.bind_service_method(self.load_var, False, visible=False)
|
|
self.sheerka.bind_service_method(self.record_internal_var, True, visible=False)
|
|
self.sheerka.bind_service_method(self.load_internal_var, False, visible=False)
|
|
self.sheerka.bind_service_method(self.delete_var, True, visible=False)
|
|
self.sheerka.bind_service_method(self.set_var, True)
|
|
self.sheerka.bind_service_method(self.get_var, False)
|
|
self.sheerka.bind_service_method(self.list_vars, False)
|
|
|
|
cache = Cache().auto_configure(self.VARIABLES_ENTRY)
|
|
self.sheerka.om.register_cache(self.VARIABLES_ENTRY, cache, True, True)
|
|
cache.populate(lambda sdp: sdp.list(self.VARIABLES_ENTRY), lambda var: var.get_key())
|
|
|
|
internal_vars = Cache().auto_configure(self.INTERNAL_VARIABLES_ENTRY)
|
|
self.sheerka.om.register_cache(self.INTERNAL_VARIABLES_ENTRY, internal_vars, False, False)
|
|
|
|
def initialize_deferred(self, context, first_time):
|
|
# update bound variables
|
|
for who, keys in self.bound_variables.items():
|
|
for key in keys:
|
|
if (variable := self.sheerka.om.get(self.VARIABLES_ENTRY, f"{who}|{key}")) is not NotFound:
|
|
service = self.sheerka if who == self.sheerka.name else self.sheerka.services[who]
|
|
setattr(service, key, variable.value)
|
|
|
|
def record_var(self, context, who, key, value):
|
|
"""
|
|
|
|
:param context:
|
|
:param who: entity that owns the key (acts as a namespace)
|
|
:param key:
|
|
:param value:
|
|
:return:
|
|
"""
|
|
|
|
variable = Variable(context.event.get_digest(), who, key, value, None)
|
|
self.sheerka.om.put(self.VARIABLES_ENTRY, variable.get_key(), variable)
|
|
|
|
# TODO: manage credentials
|
|
if who in self.bound_variables and key in self.bound_variables[who]:
|
|
service = self.sheerka if who == self.sheerka.name else self.sheerka.services[who]
|
|
setattr(service, key, value)
|
|
|
|
def load_var(self, who, key):
|
|
variable = self.sheerka.om.get(self.VARIABLES_ENTRY, who + "|" + key)
|
|
if variable is NotFound:
|
|
return NotFound
|
|
|
|
return variable.value
|
|
|
|
def record_internal_var(self, context, who, key, value):
|
|
"""
|
|
Stores the value in the internal cache
|
|
This cache is not pushed to the remote repository
|
|
:param context:
|
|
:param who: entity that owns the key (acts as a namespace)
|
|
:param key:
|
|
:param value:
|
|
"""
|
|
self.sheerka.om.put(self.INTERNAL_VARIABLES_ENTRY, f"{who}|{key}", InternalObj(value))
|
|
|
|
def load_internal_var(self, who, key):
|
|
value = self.sheerka.om.get(self.INTERNAL_VARIABLES_ENTRY, f"{who}|{key}")
|
|
return NotFound if value is NotFound else value.obj
|
|
|
|
def delete_var(self, context, who, key):
|
|
self.sheerka.om.delete(self.VARIABLES_ENTRY, who + "|" + key)
|
|
|
|
def set_var(self, context, key, value):
|
|
self.record_var(context, context.event.user_id, key, value)
|
|
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
|
|
|
def get_var(self, context, key):
|
|
return self.load_var(context.event.user_id, key)
|
|
|
|
def list_vars(self, context, all_vars=False):
|
|
if all_vars:
|
|
res = [str(v) for v in self.sheerka.om.copy(self.VARIABLES_ENTRY).values()]
|
|
else:
|
|
res = [str(v) for v in self.sheerka.om.copy(self.VARIABLES_ENTRY).values() if
|
|
v.who == context.event.user_id]
|
|
return res
|