jaseci 1.4.0.18__py3-none-any.whl → 1.4.0.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jaseci might be problematic. Click here for more details.

Files changed (42) hide show
  1. jaseci/VERSION +1 -1
  2. jaseci/cli_tools/jsctl.py +41 -2
  3. jaseci/cli_tools/tests/test_jsctl.py +11 -0
  4. jaseci/extens/act_lib/internal.py +2 -1
  5. jaseci/extens/act_lib/std.py +7 -0
  6. jaseci/extens/act_lib/tests/test_std_lib.py +3 -1
  7. jaseci/extens/api/jsorc_api.py +41 -1
  8. jaseci/extens/api/walker_api.py +9 -0
  9. jaseci/jac/interpreter/architype_interp.py +63 -28
  10. jaseci/jac/interpreter/interp.py +54 -158
  11. jaseci/jac/interpreter/sentinel_interp.py +73 -5
  12. jaseci/jac/interpreter/walker_interp.py +27 -38
  13. jaseci/jac/ir/ast.py +9 -1
  14. jaseci/jac/jac.g4 +5 -4
  15. jaseci/jac/jac_parse/jacListener.py +8 -8
  16. jaseci/jac/jac_parse/jacParser.py +1167 -1154
  17. jaseci/jac/machine/jac_scope.py +23 -30
  18. jaseci/jac/machine/machine_state.py +76 -12
  19. jaseci/jsorc/jsorc.py +92 -79
  20. jaseci/jsorc/live_actions.py +29 -24
  21. jaseci/jsorc/redis.py +7 -5
  22. jaseci/prim/{action.py → ability.py} +44 -31
  23. jaseci/prim/architype.py +26 -8
  24. jaseci/prim/obj_mixins.py +5 -0
  25. jaseci/prim/sentinel.py +3 -1
  26. jaseci/prim/walker.py +7 -5
  27. jaseci/tests/jac_test_progs.py +9 -0
  28. jaseci/tests/test_jac.py +3 -3
  29. jaseci/tests/test_node.py +9 -12
  30. jaseci/tests/test_progs.py +16 -1
  31. jaseci/tests/test_stack.py +22 -0
  32. jaseci/utils/actions/actions_optimizer.py +23 -8
  33. jaseci/utils/gprof2dot.py +3786 -0
  34. jaseci/utils/json_handler.py +5 -1
  35. jaseci/utils/utils.py +52 -21
  36. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/METADATA +2 -2
  37. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/RECORD +41 -41
  38. jaseci/prim/item.py +0 -29
  39. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/LICENSE +0 -0
  40. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/WHEEL +0 -0
  41. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/entry_points.txt +0 -0
  42. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/top_level.txt +0 -0
@@ -3,30 +3,29 @@ Variable scope manager for Jac
3
3
 
4
4
  Utility for all runtime interaction with variables in different scopes
5
5
  """
6
- from jaseci.utils.id_list import IdList
7
6
  from jaseci.jac.machine.jac_value import JacValue
8
7
  from jaseci.jsorc.live_actions import get_global_actions
9
8
 
10
- global_action_sets = None
11
-
12
9
 
13
10
  class JacScope:
14
- def __init__(self, parent, has_obj, action_sets):
11
+ def __init__(self, parent, name, has_obj=None, here=None, visitor=None):
15
12
  self.parent = parent
13
+ self.name = name
16
14
  self.local_scope = {}
17
15
  self.has_obj = has_obj if has_obj else self
18
16
  self.context = {}
19
- self.action_sets = action_sets
17
+ self.action_sets = []
18
+ self._start_time = 0 # For profiling
19
+ self._total_time = 0 # For profiling
20
+ self._cum_start_time = None
21
+ self.set_refs(here, visitor)
20
22
  self.setup_actions()
21
23
 
22
24
  def setup_actions(self):
23
- global global_action_sets
24
- if global_action_sets is None:
25
- global_action_sets = self.group_actions(get_global_actions())
26
25
  allactions = []
27
26
  for i in self.action_sets:
28
27
  allactions += i.obj_list()
29
- self.action_sets = global_action_sets
28
+ self.action_sets = get_global_actions()
30
29
  for i in allactions:
31
30
  self.add_action(i)
32
31
 
@@ -40,33 +39,27 @@ class JacScope:
40
39
  else:
41
40
  self.action_sets[group] = act
42
41
 
43
- def group_actions(self, act_list):
44
- action_sets = {}
45
- for act in act_list:
46
- group = act.name.split(".")[0]
47
- if "." in act.name:
48
- if group not in action_sets.keys():
49
- action_sets[group] = {}
50
- action = act.name.split(".")[1]
51
- action_sets[group][action] = act
52
- else:
53
- action_sets[group] = act
54
- return action_sets
55
-
56
- def set_agent_refs(self, cur_node, cur_walker):
57
- self.local_scope["here"] = cur_node
58
- self.local_scope["visitor"] = cur_walker
59
-
60
- def inherit_agent_refs(self, src_scope, src_node): # used for calls of abilities
61
- self.local_scope["here"] = src_node
62
- self.local_scope["visitor"] = src_scope.local_scope["visitor"]
42
+ def set_refs(self, here, visitor):
43
+ self.local_scope["here"] = here
44
+ self.local_scope["visitor"] = visitor
45
+ self.action_sets = []
46
+ if here:
47
+ self.action_sets += [here.get_architype().get_all_abilities()]
48
+ if visitor:
49
+ self.action_sets += [visitor.get_architype().get_all_abilities()]
63
50
 
64
- def get_aganet_refs(self):
51
+ def get_refs(self):
65
52
  return {
66
53
  "here": self.local_scope["here"],
67
54
  "visitor": self.local_scope["visitor"],
68
55
  }
69
56
 
57
+ def here(self):
58
+ return self.local_scope["here"]
59
+
60
+ def visitor(self):
61
+ return self.local_scope["visitor"]
62
+
70
63
  def find_live_attr(self, name, allow_read_only=True):
71
64
  """Finds binding for variable if not in standard scope"""
72
65
  # check if var is in walker's context
@@ -19,12 +19,16 @@ from jaseci.prim.edge import Edge
19
19
  from jaseci.prim.node import Node
20
20
  from jaseci.jac.machine.jac_value import JacValue
21
21
  from jaseci.jac.jsci_vm.op_codes import JsCmp
22
+ import time
22
23
 
23
24
 
24
25
  class MachineState:
25
26
  """Shared interpreter class across both sentinels and walkers"""
26
27
 
27
- def __init__(self, parent_override=None, caller=None):
28
+ recur_detect_set = []
29
+ profile_stack = [None]
30
+
31
+ def __init__(self):
28
32
  self.report = []
29
33
  self.report_status = None
30
34
  self.report_custom = None
@@ -32,10 +36,6 @@ class MachineState:
32
36
  self.runtime_errors = []
33
37
  self.yielded_walkers_ids = IdList(self)
34
38
  self.ignore_node_ids = IdList(self)
35
- self._parent_override = parent_override
36
- if not isinstance(self, Element) and caller:
37
- self._m_id = caller._m_id
38
- self._h = caller._h
39
39
  self._scope_stack = [None]
40
40
  self._jac_scope = None
41
41
  self._relevant_edges = []
@@ -46,18 +46,14 @@ class MachineState:
46
46
  self._loop_limit = 10000
47
47
  self._cur_jac_ast = Ast("none")
48
48
  self._write_candidate = None
49
+ self._mast = self.get_master()
50
+
49
51
  self.inform_hook()
50
52
 
51
53
  def inform_hook(self):
52
54
  if hasattr(self, "_h"):
53
55
  self._h._machine = self
54
56
 
55
- def parent(self): # parent here is always a sentinel
56
- if self._parent_override:
57
- return self._parent_override
58
- else:
59
- return Element.parent(self)
60
-
61
57
  def reset(self):
62
58
  self.report = []
63
59
  self.report_status = None
@@ -69,12 +65,80 @@ class MachineState:
69
65
  self._stopped = None
70
66
 
71
67
  def push_scope(self, scope: JacScope):
68
+ self.profile_pause()
72
69
  self._scope_stack.append(scope)
73
70
  self._jac_scope = scope
71
+ MachineState.profile_stack.append(self._jac_scope)
72
+ self.profile_in()
73
+ MachineState.recur_detect_set.append(self.call_name())
74
74
 
75
75
  def pop_scope(self):
76
+ MachineState.recur_detect_set.remove(self.call_name())
77
+ self.profile_out()
76
78
  self._scope_stack.pop()
77
79
  self._jac_scope = self._scope_stack[-1]
80
+ MachineState.profile_stack.pop()
81
+ self.profile_unpause()
82
+
83
+ def profile_in(self):
84
+ if self._mast and self._mast._profiling:
85
+ self._jac_scope._start_time = time.time()
86
+ self._jac_scope._cum_start_time = time.time()
87
+
88
+ def profile_out(self):
89
+ # profile_jac_scope = MachineState.profile_stack[-1] # refactor and clean
90
+ if self._mast and self._mast._profiling:
91
+ name = self.call_name()
92
+ if name not in self._mast._jac_profile:
93
+ self._mast._jac_profile[name] = {
94
+ "calls": 1,
95
+ "u_calls": 0 if name in MachineState.recur_detect_set else 1,
96
+ "tot_time": self._jac_scope._total_time
97
+ + (time.time() - self._jac_scope._start_time),
98
+ "cum_time": 0
99
+ if name in MachineState.recur_detect_set
100
+ else time.time() - self._jac_scope._cum_start_time,
101
+ }
102
+ else:
103
+ c = self._mast._jac_profile[name]["calls"]
104
+ u = self._mast._jac_profile[name]["u_calls"]
105
+ t = self._mast._jac_profile[name]["tot_time"]
106
+ p = self._mast._jac_profile[name]["cum_time"]
107
+ self._mast._jac_profile[name]["calls"] = c + 1
108
+ self._mast._jac_profile[name]["u_calls"] = (
109
+ u if name in MachineState.recur_detect_set else u + 1
110
+ )
111
+ self._mast._jac_profile[name][
112
+ "tot_time"
113
+ ] += self._jac_scope._total_time + (
114
+ time.time() - self._jac_scope._start_time
115
+ )
116
+
117
+ self._mast._jac_profile[name]["cum_time"] = (
118
+ p
119
+ if name in MachineState.recur_detect_set
120
+ else (p + time.time() - self._jac_scope._cum_start_time)
121
+ )
122
+
123
+ def call_name(self):
124
+ return f"{self.kind}::{self.name}:{self._jac_scope.name}"
125
+
126
+ def profile_pause(self):
127
+ _jac_scope = MachineState.profile_stack[-1] # refactor and clean
128
+ if self._mast and self._mast._profiling and _jac_scope:
129
+ _jac_scope._total_time += time.time() - _jac_scope._start_time
130
+ _jac_scope._start_time = 0
131
+
132
+ def profile_unpause(self):
133
+ _jac_scope = MachineState.profile_stack[-1] # refactor and clean
134
+ if self._mast and self._mast._profiling and _jac_scope:
135
+ _jac_scope._start_time = time.time()
136
+
137
+ def here(self):
138
+ return self._scope_stack[-1].here() if self._scope_stack[-1] else None
139
+
140
+ def visitor(self):
141
+ return self._scope_stack[-1].visitor() if self._scope_stack[-1] else None
78
142
 
79
143
  def set_cur_ast(self, jac_ast):
80
144
  self._cur_jac_ast = jac_ast
@@ -164,7 +228,7 @@ class MachineState:
164
228
  """
165
229
  ret = JacSet()
166
230
  if not location:
167
- location = self.current_node
231
+ location = self.here()
168
232
  for i in edge_set.obj_list():
169
233
  ret.add_obj(i.opposing_node(location))
170
234
  return ret
jaseci/jsorc/jsorc.py CHANGED
@@ -3,7 +3,7 @@ import psycopg2
3
3
 
4
4
  from time import sleep
5
5
  from copy import deepcopy
6
- from json import dumps, loads
6
+ from json import dumps
7
7
  from datetime import datetime
8
8
  from typing import TypeVar, Any, Union
9
9
 
@@ -47,6 +47,7 @@ class JsOrc:
47
47
 
48
48
  # ------------------ COMMONS ------------------ #
49
49
 
50
+ _config = None
50
51
  _backoff_interval = 10
51
52
  _running_interval = 0
52
53
  __running__ = False
@@ -68,16 +69,23 @@ class JsOrc:
68
69
  key=lambda item: (-item["priority"], -item["date_added"]),
69
70
  )
70
71
 
72
+ @classmethod
73
+ def configure(cls):
74
+ config: dict = cls.settings("JSORC_CONFIG")
75
+
76
+ if cls.db_check():
77
+ hook = cls.hook()
78
+ config = hook.get_or_create_glob("JSORC_CONFIG", config)
79
+
80
+ cls._config = config
81
+ cls._backoff_interval = max(5, config.get("backoff_interval", 10))
82
+ cls._regeneration_queues = config.get("pre_loaded_services", [])
83
+
71
84
  @classmethod
72
85
  def run(cls):
73
86
  if not cls.__running__:
74
87
  cls.__running__ == True
75
- config: dict = cls.settings("JSORC_CONFIG")
76
- if cls.db_check():
77
- hook = cls.hook()
78
- config = hook.get_or_create_glob("JSORC_CONFIG", config)
79
- cls._backoff_interval = max(5, config.get("backoff_interval", 10))
80
- cls._regeneration_queues = config.get("pre_loaded_services", [])
88
+ cls.configure()
81
89
  cls.push_interval(1)
82
90
 
83
91
  @classmethod
@@ -466,87 +474,92 @@ class JsOrc:
466
474
  from jaseci.utils.actions.actions_manager import ActionManager
467
475
 
468
476
  kube = cls.svc("kube", KubeService)
469
- while cls._regeneration_queues:
470
- regeneration_queue = cls._regeneration_queues.pop(0)
477
+ regeneration_queues = cls._regeneration_queues.copy()
478
+ cls._regeneration_queues.clear()
479
+ while regeneration_queues:
480
+ regeneration_queue = regeneration_queues.pop(0)
471
481
  service = cls.svc(regeneration_queue)
472
482
  hook = cls.hook(use_proxy=service.source["proxy"])
473
483
  if not service.is_running() and service.enabled and service.automated:
474
484
  if service.manifest and kube.is_running():
475
- manifest = kube.resolve_manifest(
476
- hook.get_or_create_glob(
477
- service.source["manifest"], service.manifest
478
- ),
479
- *cls.overrided_namespace(
480
- regeneration_queue, service.manifest_type
481
- ),
482
- )
483
-
484
- rmhists: dict = hook.get_or_create_glob(
485
- "RESOLVED_MANIFEST_HISTORY", {}
486
- )
487
-
488
- _rmhist = rmhists.get(service.source["manifest"], [{}])[0]
489
- rmhist = deepcopy(_rmhist)
490
-
491
- for kind, confs in manifest.items():
492
- for name, conf in confs.items():
493
- namespace = conf["metadata"].get("namespace")
485
+ try:
486
+ manifest = kube.resolve_manifest(
487
+ hook.get_or_create_glob(
488
+ service.source["manifest"], service.manifest
489
+ ),
490
+ *cls.overrided_namespace(
491
+ regeneration_queue, service.manifest_type
492
+ ),
493
+ )
494
+
495
+ rmhists: dict = hook.get_or_create_glob(
496
+ "RESOLVED_MANIFEST_HISTORY", {}
497
+ )
498
+
499
+ _rmhist = rmhists.get(service.source["manifest"], [{}])[0]
500
+ rmhist = deepcopy(_rmhist)
501
+
502
+ for kind, confs in manifest.items():
503
+ for name, conf in confs.items():
504
+ namespace = conf["metadata"].get("namespace")
505
+
506
+ if kind in rmhist and name in rmhist[kind]:
507
+ rmhist[kind].pop(name, None)
508
+
509
+ res = kube.read(kind, name, namespace)
510
+ if hasattr(res, "status") and res.status == 404:
511
+ kube.create(kind, name, conf, namespace)
512
+ elif not isinstance(res, ApiException):
513
+ config_version = 1
514
+
515
+ if isinstance(res, dict):
516
+ if "labels" in res["metadata"]:
517
+ config_version = (
518
+ res["metadata"]
519
+ .get("labels", {})
520
+ .get("config_version", 1)
521
+ )
522
+ elif res.metadata.labels:
523
+ config_version = res.metadata.labels.get(
524
+ "config_version", 1
525
+ )
494
526
 
495
- if kind in rmhist and name in rmhist[kind]:
496
- rmhist[kind].pop(name, None)
527
+ if config_version != conf.get("metadata").get(
528
+ "labels", {}
529
+ ).get("config_version", 1):
530
+ kube.patch(kind, name, conf, namespace)
531
+
532
+ for kind, confs in rmhist.items():
533
+ for name, conf in confs.items():
534
+ namespace = conf["metadata"].get("namespace")
535
+ res = kube.read(kind, name, namespace, quiet=True)
536
+ if not isinstance(res, ApiException) and (
537
+ (isinstance(res, dict) and res.get("metadata"))
538
+ or res.metadata
539
+ ):
540
+ if kind not in cls.settings(
541
+ "UNSAFE_KINDS"
542
+ ) or service.manifest_unsafe_paraphrase == cls.settings(
543
+ "UNSAFE_PARAPHRASE"
544
+ ):
545
+ kube.delete(kind, name, namespace)
546
+ else:
547
+ logger.info(
548
+ f"You don't have permission to delete `{kind}` for `{name}` with namespace `{namespace}`!"
549
+ )
497
550
 
498
- res = kube.read(kind, name, namespace)
499
- if hasattr(res, "status") and res.status == 404:
500
- kube.create(kind, name, conf, namespace)
501
- elif not isinstance(res, ApiException):
502
- config_version = 1
551
+ if _rmhist != manifest:
552
+ if service.source["manifest"] not in rmhists:
553
+ rmhists[service.source["manifest"]] = [manifest]
554
+ else:
555
+ rmhists[service.source["manifest"]].insert(0, manifest)
556
+ hook.save_glob("RESOLVED_MANIFEST_HISTORY", dumps(rmhists))
557
+ hook.commit()
503
558
 
504
- if isinstance(res, dict):
505
- if "labels" in res["metadata"]:
506
- config_version = (
507
- res["metadata"]
508
- .get("labels", {})
509
- .get("config_version", 1)
510
- )
511
- elif res.metadata.labels:
512
- config_version = res.metadata.labels.get(
513
- "config_version", 1
514
- )
515
-
516
- if config_version != conf.get("metadata").get(
517
- "labels", {}
518
- ).get("config_version", 1):
519
- kube.patch(kind, name, conf, namespace)
520
-
521
- for kind, confs in rmhist.items():
522
- for name, conf in confs.items():
523
- namespace = conf["metadata"].get("namespace")
524
- res = kube.read(kind, name, namespace, quiet=True)
525
- if not isinstance(res, ApiException) and (
526
- (isinstance(res, dict) and res.get("metadata"))
527
- or res.metadata
528
- ):
529
- if kind not in cls.settings(
530
- "UNSAFE_KINDS"
531
- ) or service.manifest_unsafe_paraphrase == cls.settings(
532
- "UNSAFE_PARAPHRASE"
533
- ):
534
- kube.delete(kind, name, namespace)
535
- else:
536
- logger.info(
537
- f"You don't have permission to delete `{kind}` for `{name}` with namespace `{namespace}`!"
538
- )
539
-
540
- if _rmhist != manifest:
541
- if service.source["manifest"] not in rmhists:
542
- rmhists[service.source["manifest"]] = [manifest]
543
- else:
544
- rmhists[service.source["manifest"]].insert(0, manifest)
545
- hook.save_glob("RESOLVED_MANIFEST_HISTORY", dumps(rmhists))
546
- hook.commit()
559
+ except Exception as e:
560
+ logger.error(f"Unhandled exception: {e}")
547
561
 
548
562
  cls.svc_reset(regeneration_queue)
549
- sleep(1)
550
563
 
551
564
  action_manager = cls.get("action_manager", ActionManager)
552
565
  action_manager.optimize(jsorc_interval=cls._backoff_interval)
@@ -16,6 +16,9 @@ live_actions = {} # {"act.func": func_obj, ...}
16
16
  live_action_modules = {} # {__module__: ["act.func1", "act.func2", ...], ...}
17
17
  action_configs = {} # {"module_name": {}, ...}
18
18
 
19
+ glob_act_group = {} # {"group_name": {"act_name": action, ...}, ...}
20
+ glob_act_hook = None
21
+
19
22
 
20
23
  def jaseci_action(act_group=None, aliases=list(), allow_remote=False):
21
24
  """Decorator for Jaseci Action interface"""
@@ -215,38 +218,40 @@ def get_global_actions():
215
218
  Loads all global action hooks for use by Jac programs
216
219
  Attaches globals to mem_hook
217
220
  """
218
- from jaseci.prim.action import Action
221
+ from jaseci.prim.ability import Ability
219
222
  from jaseci.jsorc.memory import MemoryHook
220
223
 
221
- global_action_list = []
222
- hook = MemoryHook()
223
- for i in live_actions.keys():
224
- if (
225
- i.startswith("std.")
226
- or i.startswith("file.")
227
- or i.startswith("net.")
228
- or i.startswith("rand.")
229
- or i.startswith("vector.")
230
- or i.startswith("request.")
231
- or i.startswith("date.")
232
- or i.startswith("jaseci.")
233
- or i.startswith("internal.")
234
- or i.startswith("zip.")
235
- or i.startswith("webtool.")
236
- or i.startswith("url.")
237
- or i.startswith("regex.")
238
- ):
239
- global_action_list.append(
240
- Action(
224
+ if not glob_act_group:
225
+ glob_act_hook = MemoryHook()
226
+ for i in live_actions.keys():
227
+ name = i.split(".")
228
+ if name[0] in [
229
+ "std",
230
+ "file",
231
+ "net",
232
+ "rand",
233
+ "vector",
234
+ "request",
235
+ "date",
236
+ "jaseci",
237
+ "internal",
238
+ "zip",
239
+ "webtool",
240
+ "url",
241
+ "regex",
242
+ ]:
243
+ if name[0] not in glob_act_group:
244
+ glob_act_group[name[0]] = {}
245
+ glob_act_group[name[0]][name[1]] = Ability(
241
246
  m_id=0,
242
- h=hook,
247
+ h=glob_act_hook,
243
248
  mode="public",
244
249
  name=i,
250
+ kind="ability",
245
251
  value=i,
246
252
  persist=False,
247
253
  )
248
- )
249
- return global_action_list
254
+ return glob_act_group
250
255
 
251
256
 
252
257
  def unload_remote_actions(url):
jaseci/jsorc/redis.py CHANGED
@@ -5,7 +5,7 @@ core engine.
5
5
  import json
6
6
 
7
7
  import jaseci as core_mod
8
- from jaseci.utils.json_handler import JaseciJsonDecoder
8
+ from jaseci.utils.json_handler import JaseciJsonDecoder, jsci_dict_normalize
9
9
  from jaseci.jsorc.memory import MemoryHook
10
10
  from jaseci.jsorc.jsorc import JsOrc
11
11
  from jaseci.extens.svc.redis_svc import RedisService
@@ -45,11 +45,13 @@ class RedisHook(MemoryHook):
45
45
  j_master = jdict["j_master"]
46
46
  class_for_type = self.find_class_and_import(j_type, core_mod)
47
47
  ret_obj = class_for_type(h=self, m_id=j_master, auto_save=False)
48
- ret_obj.json_load(loaded_obj)
48
+ jsci_dict_normalize(jdict, parent_obj=ret_obj)
49
+ ret_obj.dict_load(jdict)
49
50
 
50
51
  super().commit_obj_to_cache(ret_obj)
51
- return ret_obj
52
-
52
+ obj = ret_obj
53
+ if obj:
54
+ obj._persist = True
53
55
  return obj
54
56
 
55
57
  def has_obj_in_store(self, item_id):
@@ -122,7 +124,7 @@ class RedisHook(MemoryHook):
122
124
  def decommit_obj_from_cache(self, item):
123
125
  super().decommit_obj_from_cache(item)
124
126
 
125
- if self.redis.is_running():
127
+ if item._persist and self.redis.is_running():
126
128
  self.redis.delete(item.jid)
127
129
 
128
130
  ###################################################
@@ -3,7 +3,7 @@ Action class for Jaseci
3
3
 
4
4
  Each action has an id, name, timestamp and it's set of edges.
5
5
  """
6
- from .item import Item
6
+ from jaseci.prim.element import Element
7
7
  from jaseci.jsorc.live_actions import live_actions
8
8
  from jaseci.jac.jac_set import JacSet
9
9
  import inspect
@@ -11,53 +11,56 @@ import time
11
11
 
12
12
  from jaseci.jsorc.jsorc import JsOrc
13
13
  from jaseci.utils.actions.actions_manager import ActionManager
14
+ from jaseci.jac.ir.jac_code import JacCode
15
+ from jaseci.jac.interpreter.interp import Interp
16
+ from jaseci.jac.machine.jac_scope import JacScope
14
17
 
15
- # ACTION_PACKAGE = 'jaseci.actions.'
16
18
 
17
-
18
- class Action(Item):
19
+ class Ability(Element, JacCode, Interp):
19
20
  """
20
- Action class for Jaseci
21
-
22
- preset_in_out holds a set of parameters in the form of lists of context
23
- objects that are to be used from whereever those contexts are attached
24
- e.g., (nodes, edges, walkers, etc). This is used by Jac's runtime
25
- engine to support preset actions in nodes
26
- access_list is used by walker to decide what to trigger
21
+ Abilities class for Jaseci
27
22
  """
28
23
 
29
- def __init__(self, preset_in_out=None, access_list=None, **kwargs):
24
+ def __init__(
25
+ self, code_ir=None, preset_in_out=None, access_list=None, *args, **kwargs
26
+ ):
30
27
  self.preset_in_out = preset_in_out # Not using _ids convention
31
28
  self.access_list = access_list
32
- Item.__init__(self, **kwargs)
29
+ Element.__init__(self, *args, **kwargs)
30
+ JacCode.__init__(self, code_ir=code_ir)
31
+ Interp.__init__(self)
33
32
 
34
- def do_auto_conversions(self, args, params):
33
+ def run_ability(self, here, visitor):
35
34
  """
36
- Automatically make conversions for jac to internal, e.g., list to jac_set
35
+ Run ability
37
36
  """
37
+ Interp.__init__(self) # Reset before as result need to be absorbed after
38
+ self.push_scope(
39
+ JacScope(
40
+ parent=self,
41
+ name=f"a_run:{self.get_jac_ast().loc_str()}",
42
+ has_obj=here,
43
+ here=here,
44
+ visitor=visitor,
45
+ )
46
+ )
47
+ self.run_code_block(self.get_jac_ast())
48
+ self.pop_scope()
38
49
 
39
- for i in args.annotations.keys():
40
- if args.annotations[i] == JacSet:
41
- idx = args.args.index(i)
42
- if idx < len(params["args"]):
43
- params["args"][idx] = JacSet(in_list=params["args"][idx])
44
- if i in params["kwargs"]:
45
- params["kwargs"][i] = JacSet(in_list=params["kwargs"][i])
46
-
47
- def trigger(self, param_list, scope, interp):
50
+ def run_action(self, param_list, scope, interp):
48
51
  """
49
52
  param_list should be passed as list of values to lib functions
50
53
  Also note that Jac stores preset_in_out as input/output list of hex
51
54
  ids since preset_in_out doesn't use _ids convention
52
55
  """
53
- if not interp.check_builtin_action(self.value):
54
- interp.rt_error(f"Cannot execute {self.value} - Not Found")
56
+ action_name = self.name
57
+ if not interp.check_builtin_action(action_name):
58
+ interp.rt_error(f"Cannot execute {action_name} - Not Found")
55
59
  return None
56
- func = live_actions[self.value]
60
+ func = live_actions[action_name]
57
61
  args = inspect.getfullargspec(func)
58
62
  self.do_auto_conversions(args, param_list)
59
63
  args = args[0] + args[4]
60
- hook = scope.parent._h
61
64
 
62
65
  action_manager = JsOrc.get("action_manager", ActionManager)
63
66
  action_manager.pre_action_call_hook()
@@ -91,7 +94,17 @@ class Action(Item):
91
94
  )
92
95
  raise
93
96
  t = time.time() - ts
94
-
95
- action_manager.post_action_call_hook(self.value, t)
96
-
97
+ action_manager.post_action_call_hook(action_name, t)
97
98
  return result
99
+
100
+ def do_auto_conversions(self, args, params):
101
+ """
102
+ Automatically make conversions for jac to internal, e.g., list to jac_set
103
+ """
104
+ for i in args.annotations.keys():
105
+ if args.annotations[i] == JacSet:
106
+ idx = args.args.index(i)
107
+ if idx < len(params["args"]):
108
+ params["args"][idx] = JacSet(in_list=params["args"][idx])
109
+ if i in params["kwargs"]:
110
+ params["kwargs"][i] = JacSet(in_list=params["kwargs"][i])