Refactored services to inherit from BaseService

This commit is contained in:
2020-05-18 09:43:05 +02:00
parent d080cbb05a
commit c822ff6a7f
15 changed files with 197 additions and 230 deletions
@@ -1,22 +1,27 @@
import core.utils
from core.builtin_concepts import BuiltinConcepts, ErrorConcept
from core.concept import Concept
from core.sheerka.services.sheerka_service import BaseService
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError
BNF_NODE_PARSER_CLASS = "parsers.BnfNodeParser_Old.BnfNodeParser"
BASE_NODE_PARSER_CLASS = "parsers.BaseNodeParser.BaseNodeParser"
class SheerkaCreateNewConcept:
class SheerkaCreateNewConcept(BaseService):
"""
Manage the creation of a new concept
"""
NAME = "CreateNewConcept"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "CreateNewConcept"
super().__init__(sheerka)
self.bnp = core.utils.get_class(BASE_NODE_PARSER_CLASS) # BaseNodeParser
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaCreateNewConcept.create_new_concept)
def create_new_concept(self, context, concept: Concept):
"""
Adds a new concept to the system
@@ -36,7 +41,7 @@ class SheerkaCreateNewConcept:
error = SheerkaDataProviderDuplicateKeyError(sheerka.CONCEPTS_BY_KEY_ENTRY + "." + concept.key,
concept)
return sheerka.ret(
self.logger_name,
self.NAME,
False,
sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED, body=concept),
error.args[0])
@@ -47,13 +52,13 @@ class SheerkaCreateNewConcept:
# update the dictionary of concepts by first key
init_ret_value = self.bnp.get_concepts_by_first_keyword(context, [concept], True)
if not init_ret_value.status:
return sheerka.ret(self.logger_name, False, ErrorConcept(init_ret_value.value))
return sheerka.ret(self.NAME, False, ErrorConcept(init_ret_value.value))
concepts_by_first_keyword = init_ret_value.body
# update resolved dictionary
init_ret_value = self.bnp.resolve_concepts_by_first_keyword(context, concepts_by_first_keyword)
if not init_ret_value.status:
return sheerka.ret(self.logger_name, False, ErrorConcept(init_ret_value.value))
return sheerka.ret(self.NAME, False, ErrorConcept(init_ret_value.value))
resolved_concepts_by_first_keyword = init_ret_value.body
concept.freeze_definition_hash()
@@ -66,5 +71,5 @@ class SheerkaCreateNewConcept:
sheerka.cache_manager.clear(sheerka.CONCEPTS_GRAMMARS_ENTRY)
# process the return if needed
ret = sheerka.ret(self.logger_name, True, sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
ret = sheerka.ret(self.NAME, True, sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
return ret
+33 -24
View File
@@ -4,6 +4,7 @@ import pprint
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.sheerka.ExecutionContext import ExecutionContext
from core.sheerka.services.sheerka_service import BaseService
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
@@ -13,9 +14,17 @@ def get_pp():
return pp
class SheerkaDump:
class SheerkaDump(BaseService):
NAME = "Dump"
def __init__(self, sheerka):
self.sheerka = sheerka
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaDump.dump_concepts, "concepts")
self.sheerka.bind_service_method(self, SheerkaDump.dump_desc, "desc")
self.sheerka.bind_service_method(self, SheerkaDump.dump_state, "state")
def dump_concepts(self):
lst = self.sheerka.sdp.list(self.sheerka.CONCEPTS_BY_ID_ENTRY)
@@ -69,28 +78,28 @@ class SheerkaDump:
first = False
def dump_history(self, page=20, start=0):
count = 0
resolved_page = page if page > 0 else 50
page_count = 0
while count < page if page > 0 else True:
history = self.sheerka.history(resolved_page, start + page_count * resolved_page)
try:
h = next(history)
except StopIteration:
break
while True:
try:
if h.result:
self.sheerka.log.info(h)
count += 1
h = next(history)
except StopIteration:
break
page_count += 1
# def dump_history(self, page=20, start=0):
# count = 0
# resolved_page = page if page > 0 else 50
# page_count = 0
#
# while count < page if page > 0 else True:
# history = self.sheerka.history(resolved_page, start + page_count * resolved_page)
# try:
# h = next(history)
# except StopIteration:
# break
#
# while True:
# try:
# if h.result:
# self.sheerka.log.info(h)
# count += 1
# h = next(history)
# except StopIteration:
# break
#
# page_count += 1
def dump_state(self):
snapshot = self.sheerka.sdp.get_snapshot(SheerkaDataProvider.HeadFile)
@@ -1,6 +1,7 @@
from core.builtin_concepts import BuiltinConcepts
from core.builtin_helpers import expect_one, only_successful
from core.concept import Concept, DoNotResolve, ConceptParts, InfiniteRecursionResolved
from core.sheerka.services.sheerka_service import BaseService
CONCEPT_EVALUATION_STEPS = [
BuiltinConcepts.BEFORE_EVALUATION,
@@ -8,10 +9,14 @@ CONCEPT_EVALUATION_STEPS = [
BuiltinConcepts.AFTER_EVALUATION]
class SheerkaEvaluateConcept:
class SheerkaEvaluateConcept(BaseService):
NAME = "EvaluateConcept"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "EvaluateConcept"
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaEvaluateConcept.evaluate_concept)
@staticmethod
def infinite_recursion_detected(context, concept):
@@ -51,14 +56,14 @@ class SheerkaEvaluateConcept:
if parent.who == context.who and parent.desc == context.desc:
body = parent.obj.metadata.body
try:
return self.sheerka.ret(self.logger_name, True, InfiniteRecursionResolved(eval(body)))
return self.sheerka.ret(self.NAME, True, InfiniteRecursionResolved(eval(body)))
except Exception:
pass
concepts_found.add(parent.obj)
parent = parent.get_parent()
return self.sheerka.ret(
self.logger_name,
self.NAME,
False,
self.sheerka.new(BuiltinConcepts.CHICKEN_AND_EGG, body=concepts_found))
@@ -71,10 +76,11 @@ class SheerkaEvaluateConcept:
:param logger:
:return:
"""
def is_only_successful(r):
# return False
# return False
return context.sheerka.isinstance(r, BuiltinConcepts.RETURN_VALUE) and \
context.sheerka.isinstance(r.body, BuiltinConcepts.ONLY_SUCCESSFUL)
context.sheerka.isinstance(r.body, BuiltinConcepts.ONLY_SUCCESSFUL)
steps = [BuiltinConcepts.BEFORE_PARSING, BuiltinConcepts.PARSING, BuiltinConcepts.AFTER_PARSING]
for part_key in ConceptParts:
@@ -134,7 +140,7 @@ class SheerkaEvaluateConcept:
return ret_val.body
desc = f"Evaluating {current_prop} (concept={current_concept})"
context.log(desc, self.logger_name)
context.log(desc, self.NAME)
with context.push(desc=desc, obj=current_concept) as sub_context:
if force_evaluation:
+21 -15
View File
@@ -1,18 +1,24 @@
import core.utils
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
from core.sheerka.services.sheerka_service import BaseService
NO_MATCH = "** No Match **"
class SheerkaExecute:
class SheerkaExecute(BaseService):
"""
Manage the execution of a process flow
"""
def __init__(self, sheerka):
self.sheerka = sheerka
NAME = "Execute"
def call_parsers(self, execution_context, return_values):
def __init__(self, sheerka):
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaExecute.execute)
def call_parsers(self, context, return_values):
# return_values must be a list
if not isinstance(return_values, list):
@@ -35,7 +41,7 @@ class SheerkaExecute:
# group the parsers by priorities
instantiated_parsers = [parser(sheerka=self.sheerka) for parser in self.sheerka.parsers.values()]
instantiated_parsers = self.preprocess(execution_context, instantiated_parsers)
instantiated_parsers = self.preprocess(context, instantiated_parsers)
grouped_parsers = {}
for parser in [p for p in instantiated_parsers if p.enabled]:
@@ -57,10 +63,10 @@ class SheerkaExecute:
# if self.sheerka.log.isEnabledFor(logging.DEBUG):
# debug_text = "'" + to_parse + "'" if isinstance(to_parse, str) \
# else "'" + BaseParser.get_text_from_tokens(to_parse) + "' as tokens"
# execution_context.log(f"Parsing {debug_text}")
# context.log(f"Parsing {debug_text}")
with execution_context.push(desc=f"Parsing using {parser.name}",
logger=parser.verbose_log) as sub_context:
with context.push(desc=f"Parsing using {parser.name}",
logger=parser.verbose_log) as sub_context:
sub_context.add_inputs(to_parse=to_parse)
res = parser.parse(sub_context, to_parse)
if res is not None:
@@ -94,7 +100,7 @@ class SheerkaExecute:
result = core.utils.remove_list_from_list(result, user_inputs)
return result
def call_evaluators(self, execution_context, return_values, process_step):
def call_evaluators(self, context, return_values, process_step):
# return_values must be a list
if not isinstance(return_values, list):
@@ -106,7 +112,7 @@ class SheerkaExecute:
instantiated_evaluators = [e_class() for e_class in self.sheerka.evaluators]
# pre-process evaluators if needed
instantiated_evaluators = self.preprocess(execution_context, instantiated_evaluators)
instantiated_evaluators = self.preprocess(context, instantiated_evaluators)
for evaluator in [e for e in instantiated_evaluators if e.enabled and process_step in e.steps]:
grouped_evaluators.setdefault(evaluator.priority, []).append(evaluator)
@@ -117,7 +123,7 @@ class SheerkaExecute:
# process
iteration = 0
while True:
with execution_context.push(desc=f"iteration #{iteration}", iteration=iteration) as iteration_context:
with context.push(desc=f"iteration #{iteration}", iteration=iteration) as iteration_context:
simple_digest = return_values[:]
iteration_context.add_inputs(return_values=simple_digest)
@@ -127,7 +133,7 @@ class SheerkaExecute:
evaluated_items = []
to_delete = []
for evaluator in grouped_evaluators[priority]:
evaluator = self.preprocess(execution_context, evaluator.__class__()) # fresh copy
evaluator = self.preprocess(context, evaluator.__class__()) # fresh copy
sub_context_desc = f"Evaluating using {evaluator.name} ({priority=})"
with iteration_context.push(desc=sub_context_desc, logger=evaluator.verbose_log) as sub_context:
@@ -194,10 +200,10 @@ class SheerkaExecute:
return return_values
def execute(self, execution_context, return_values, execution_steps):
def execute(self, context, return_values, execution_steps):
"""
Executes process for all initial contexts
:param execution_context:
:param context:
:param return_values:
:param execution_steps:
:return:
@@ -205,7 +211,7 @@ class SheerkaExecute:
for step in execution_steps:
copy = return_values[:] if hasattr(return_values, "__iter__") else [return_values]
with execution_context.push(step=step, iteration=0, desc=f"{step=}") as sub_context:
with context.push(step=step, iteration=0, desc=f"{step=}") as sub_context:
if step == BuiltinConcepts.PARSING:
return_values = self.call_parsers(sub_context, return_values)
@@ -1,5 +1,6 @@
from collections import namedtuple
from core.sheerka.services.sheerka_service import BaseService
from sdp.sheerkaDataProvider import Event
hist = namedtuple("HistoryTest", "text status") # tests purposes only
@@ -42,11 +43,16 @@ class History:
return self._status
class SheerkaHistoryManager:
def __init__(self, sheerka):
self.sheerka = sheerka
class SheerkaHistoryManager(BaseService):
NAME = "History"
def history(self, depth, start):
def __init__(self, sheerka):
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaHistoryManager.history)
def history(self, depth=10, start=0):
"""
Load history
:param depth: number of items
@@ -1,10 +1,15 @@
from core.builtin_concepts import BuiltinConcepts
from core.sheerka.services.sheerka_service import BaseService
class SheerkaModifyConcept:
class SheerkaModifyConcept(BaseService):
NAME = "ModifyConcept"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "ModifyConcept"
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaModifyConcept.modify_concept)
def modify_concept(self, context, concept):
old_version = self.sheerka.get_by_id(concept.id)
@@ -12,7 +17,7 @@ class SheerkaModifyConcept:
if old_version is None:
# nothing found in cache
return self.sheerka.ret(
self.logger_name, False,
self.NAME, False,
self.sheerka.new(
BuiltinConcepts.UNKNOWN_CONCEPT,
body=[("key", concept.key), ("id", concept.id)]))
@@ -20,13 +25,13 @@ class SheerkaModifyConcept:
if not self.sheerka.is_success(old_version) and concept.key != old_version.key:
# an error concept is returned
return self.sheerka.ret(
self.logger_name, False,
self.NAME, False,
old_version)
if old_version == concept:
# the concept is not modified
return self.sheerka.ret(
self.logger_name, False,
self.NAME, False,
self.sheerka.new(
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
body=concept))
@@ -37,5 +42,5 @@ class SheerkaModifyConcept:
# TODO : update resolved by first keyword
# TODO : update concepts grammars
ret = self.sheerka.ret(self.logger_name, True, self.sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
ret = self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
return ret
+30 -15
View File
@@ -1,15 +1,30 @@
import core.builtin_helpers
from cache.SetCache import SetCache
from core.ast.nodes import python_to_concept
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept, ConceptParts
from core.sheerka.services.sheerka_service import BaseService
GROUP_PREFIX = 'All_'
class SheerkaSetsManager:
class SheerkaSetsManager(BaseService):
NAME = "SetsManager"
CONCEPTS_GROUPS_ENTRY = "Concepts_Groups"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "SetsManager"
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaSetsManager.set_isa)
self.sheerka.bind_service_method(self, SheerkaSetsManager.get_set_elements)
self.sheerka.bind_service_method(self, SheerkaSetsManager.add_concept_to_set)
self.sheerka.bind_service_method(self, SheerkaSetsManager.isinset)
self.sheerka.bind_service_method(self, SheerkaSetsManager.isa)
self.sheerka.bind_service_method(self, SheerkaSetsManager.isaset)
cache = SetCache(default=lambda k: self.sheerka.sdp.get(self.CONCEPTS_GROUPS_ENTRY, k))
self.sheerka.cache_manager.register_cache(self.CONCEPTS_GROUPS_ENTRY, cache)
def set_isa(self, context, concept, concept_set):
"""
@@ -20,11 +35,11 @@ class SheerkaSetsManager:
:return:
"""
context.log(f"Setting concept {concept} is a {concept_set}", who=self.logger_name)
context.log(f"Setting concept {concept} is a {concept_set}", who=self.NAME)
if BuiltinConcepts.ISA in concept.metadata.props and concept_set in concept.metadata.props[BuiltinConcepts.ISA]:
return self.sheerka.ret(
self.logger_name,
self.NAME,
False,
self.sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_IN_SET, body=concept, concept_set=concept_set))
@@ -45,25 +60,25 @@ class SheerkaSetsManager:
:return:
"""
context.log(f"Adding concept {concept} to set {concept_set}", who=self.logger_name)
context.log(f"Adding concept {concept} to set {concept_set}", who=self.NAME)
assert concept.id
assert concept_set.id
set_elements = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, concept_set.id)
set_elements = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, concept_set.id)
if set_elements and concept.id in set_elements:
return self.sheerka.ret(
self.logger_name,
self.NAME,
False,
self.sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_IN_SET, body=concept, concept_set=concept_set))
self.sheerka.cache_manager.put(self.sheerka.CONCEPTS_GROUPS_ENTRY, concept_set.id, concept.id)
return self.sheerka.ret(self.logger_name, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
self.sheerka.cache_manager.put(self.CONCEPTS_GROUPS_ENTRY, concept_set.id, concept.id)
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
def add_concepts_to_set(self, context, concepts, concept_set):
"""Adding multiple concepts at the same time"""
context.log(f"Adding concepts {concepts} to set {concept_set}", who=self.logger_name)
context.log(f"Adding concepts {concepts} to set {concept_set}", who=self.NAME)
already_in_set = []
for concept in concepts:
res = self.add_concept_to_set(context, concept, concept_set)
@@ -77,7 +92,7 @@ class SheerkaSetsManager:
else:
body = self.sheerka.new(BuiltinConcepts.SUCCESS)
return self.sheerka.ret(self.logger_name, len(already_in_set) != len(concepts), body)
return self.sheerka.ret(self.NAME, len(already_in_set) != len(concepts), body)
def get_set_elements(self, context, concept):
"""
@@ -93,7 +108,7 @@ class SheerkaSetsManager:
return self.sheerka.new(BuiltinConcepts.NOT_A_SET, body=concept)
# first, try to see if sub_context has it's own group entry
ids = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, sub_concept.id)
ids = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, sub_concept.id)
concepts = self._get_concepts(context, ids, True)
# aggregate with en entries from its body
@@ -143,7 +158,7 @@ class SheerkaSetsManager:
if not (a.id and b.id):
return False
group_elements = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, b.id)
group_elements = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, b.id)
return group_elements and a.id in group_elements
def isa(self, a, b):
@@ -173,7 +188,7 @@ class SheerkaSetsManager:
# check if it has a group
# TODO: use cache instead of directly requesting sdp
if self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, concept.id):
if self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, concept.id):
return True
# it may be a concept that references a set
@@ -1,7 +1,8 @@
from dataclasses import dataclass
from typing import List
from core.sheerka.services.sheerka_service import ServiceObj
from cache.Cache import Cache
from core.sheerka.services.sheerka_service import ServiceObj, BaseService
@dataclass
@@ -18,10 +19,20 @@ class Variable(ServiceObj):
return f"{self.who}|{self.key}"
class SheerkaVariableManager:
class SheerkaVariableManager(BaseService):
NAME = "VariableManager"
VARIABLES_ENTRY = "Variables" # entry for admin or internal variables
def __init__(self, sheerka):
self.sheerka = sheerka
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaVariableManager.record)
self.sheerka.bind_service_method(self, SheerkaVariableManager.load)
self.sheerka.bind_service_method(self, SheerkaVariableManager.delete)
cache = Cache(default=lambda k: self.sheerka.sdp.get(self.VARIABLES_ENTRY, k))
self.sheerka.cache_manager.register_cache(self.VARIABLES_ENTRY, cache, True, True)
def record(self, context, who, key, value):
"""
@@ -34,14 +45,14 @@ class SheerkaVariableManager:
"""
variable = Variable(context.event.get_digest(), who, key, value, None)
self.sheerka.cache_manager.put(self.sheerka.VARIABLES_ENTRY, variable.get_key(), variable)
self.sheerka.cache_manager.put(self.VARIABLES_ENTRY, variable.get_key(), variable)
def load(self, who, key):
variable = self.sheerka.cache_manager.get(self.sheerka.VARIABLES_ENTRY, who + "|" + key)
variable = self.sheerka.cache_manager.get(self.VARIABLES_ENTRY, who + "|" + key)
if variable is None:
return None
return variable.value
def delete(self, context, who, key):
self.sheerka.cache_manager.delete(self.sheerka.VARIABLES_ENTRY, who + "|" + key)
self.sheerka.cache_manager.delete(self.VARIABLES_ENTRY, who + "|" + key)
@@ -12,3 +12,10 @@ class BaseService:
"""
def __init__(self, sheerka):
self.sheerka = sheerka
def initialize(self):
"""
Adds cache or bind methods
:return:
"""
pass