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
jaseci/prim/architype.py CHANGED
@@ -18,9 +18,9 @@ class Architype(Element, JacCode, ArchitypeInterp):
18
18
  self.anchor_var = None
19
19
  self.private_vars = []
20
20
  self.has_vars = []
21
- self.entry_action_ids = IdList(self)
22
- self.activity_action_ids = IdList(self)
23
- self.exit_action_ids = IdList(self)
21
+ self.entry_ability_ids = IdList(self)
22
+ self.activity_ability_ids = IdList(self)
23
+ self.exit_ability_ids = IdList(self)
24
24
 
25
25
  # async handling for walker
26
26
  self.is_async = is_async
@@ -35,12 +35,27 @@ class Architype(Element, JacCode, ArchitypeInterp):
35
35
  """
36
36
  return self.run_architype(jac_ast=self.get_jac_ast())
37
37
 
38
- def get_all_actions(self):
38
+ def get_actions(self, action_types: list):
39
39
  actions = IdList(self, auto_save=False)
40
40
  for i in self.arch_with_supers():
41
- actions += i.entry_action_ids + i.activity_action_ids + i.exit_action_ids
41
+ for j in action_types:
42
+ actions += getattr(i, j)
42
43
  return actions
43
44
 
45
+ def get_entry_abilities(self):
46
+ return self.get_actions(["entry_ability_ids"])
47
+
48
+ def get_activity_abilities(self):
49
+ return self.get_actions(["activity_ability_ids"])
50
+
51
+ def get_exit_abilities(self):
52
+ return self.get_actions(["exit_ability_ids"])
53
+
54
+ def get_all_abilities(self):
55
+ return self.get_actions(
56
+ ["entry_ability_ids", "activity_ability_ids", "exit_ability_ids"]
57
+ )
58
+
44
59
  def arch_with_supers(self):
45
60
  archs = [self]
46
61
  for i in self.super_archs:
@@ -54,6 +69,9 @@ class Architype(Element, JacCode, ArchitypeInterp):
54
69
  names += i.super_archs + [i.name]
55
70
  return names
56
71
 
72
+ def get_architype(self):
73
+ return self
74
+
57
75
  def is_instance(self, name):
58
76
  return name in self.derived_types()
59
77
 
@@ -62,9 +80,9 @@ class Architype(Element, JacCode, ArchitypeInterp):
62
80
  Destroys self from memory and persistent storage
63
81
  """
64
82
  des = (
65
- self.activity_action_ids.obj_list()
66
- + self.entry_action_ids.obj_list()
67
- + self.exit_action_ids.obj_list()
83
+ self.activity_ability_ids.obj_list()
84
+ + self.entry_ability_ids.obj_list()
85
+ + self.exit_ability_ids.obj_list()
68
86
  )
69
87
  for i in des:
70
88
  i.destroy()
jaseci/prim/obj_mixins.py CHANGED
@@ -207,6 +207,11 @@ class Hookable(Sharable):
207
207
  )
208
208
  return target._h == self._h
209
209
 
210
+ def make_persistent(self):
211
+ """Make element persistent"""
212
+ self._persist = True
213
+ self.save()
214
+
210
215
  def save(self):
211
216
  """
212
217
  Write self through hook to persistent storage
jaseci/prim/sentinel.py CHANGED
@@ -219,7 +219,9 @@ class Sentinel(Element, JacCode, SentinelInterp):
219
219
  if i["assert_block"]:
220
220
  wlk._loop_ctrl = None
221
221
  wlk.scope_and_run(
222
- jac_ir_to_ast(i["assert_block"]), run_func=wlk.run_code_block
222
+ jac_ir_to_ast(i["assert_block"]),
223
+ run_func=wlk.run_code_block,
224
+ scope_name="assert_block",
223
225
  )
224
226
  i["passed"] = True
225
227
  if not silent:
jaseci/prim/walker.py CHANGED
@@ -10,7 +10,6 @@ from jaseci.utils.utils import (
10
10
  logger,
11
11
  perf_test_start,
12
12
  perf_test_stop,
13
- perf_test_to_b64,
14
13
  exc_stack_as_str_list,
15
14
  )
16
15
  from jaseci.prim.element import Element
@@ -22,6 +21,7 @@ import hashlib
22
21
 
23
22
  from jaseci.jsorc.jsorc import JsOrc
24
23
  from jaseci.extens.svc.task_svc import TaskService
24
+ from jaseci.utils.utils import format_jac_profile
25
25
 
26
26
 
27
27
  class Walker(Element, WalkerInterp, Anchored):
@@ -40,6 +40,8 @@ class Walker(Element, WalkerInterp, Anchored):
40
40
  self.step_limit = 10000
41
41
  self.is_async = is_async
42
42
  self._to_await = False
43
+ if "persist" not in kwargs: # Default walker persistence to is_async
44
+ kwargs["persist"] = is_async
43
45
  Element.__init__(self, **kwargs)
44
46
  WalkerInterp.__init__(self)
45
47
  Anchored.__init__(self)
@@ -120,8 +122,6 @@ class Walker(Element, WalkerInterp, Anchored):
120
122
 
121
123
  def prime(self, start_node, prime_ctx=None, request_ctx=None):
122
124
  """Place walker on node and get ready to step step"""
123
- if not self.yielded:
124
- self.clear_state()
125
125
  if not self.yielded or not len(self.next_node_ids): # modus ponens
126
126
  self.next_node_ids.add_obj(start_node, push_front=True)
127
127
  if prime_ctx:
@@ -191,8 +191,10 @@ class Walker(Element, WalkerInterp, Anchored):
191
191
  report_ret["errors"] = self.runtime_errors
192
192
  report_ret["success"] = False
193
193
  if profiling:
194
- self.profile["perf"] = perf_test_stop(pr)
195
- self.profile["graph"] = perf_test_to_b64(pr)
194
+ self.profile["jac"] = format_jac_profile(self.get_master()._jac_profile)
195
+ calls, graph = perf_test_stop(pr)
196
+ self.profile["perf"] = calls
197
+ self.profile["graph"] = graph
196
198
  report_ret["profile"] = self.profile
197
199
 
198
200
  if self.for_queue():
@@ -746,3 +746,12 @@ walker a {
746
746
  }
747
747
  }
748
748
  """
749
+
750
+ json_casting = """
751
+ walker json_casting {
752
+ with entry {
753
+ report {"test": 1}.str;
754
+ report '{"test2": 2}'.dict;
755
+ }
756
+ }
757
+ """
jaseci/tests/test_jac.py CHANGED
@@ -165,10 +165,10 @@ class JacTests(TestCaseHelper, TestCase):
165
165
  """Test preset function loading"""
166
166
  from jaseci.jac.machine.jac_scope import JacScope
167
167
 
168
- JacScope(None, None, [])
169
- from jaseci.jac.machine.jac_scope import global_action_sets
168
+ JacScope(None, None)
169
+ from jaseci.jac.machine.jac_scope import get_global_actions
170
170
 
171
- self.assertGreater(len(global_action_sets), 5)
171
+ self.assertGreater(len(get_global_actions()), 5)
172
172
 
173
173
  def test_multiple_edged_between_nodes_work(self):
174
174
  """Test that multiple edges between the same two nodes are allowed"""
jaseci/tests/test_node.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from unittest import TestCase
2
2
 
3
3
  from jaseci.prim.architype import Architype
4
- from jaseci.prim import action
4
+ from jaseci.prim import ability
5
5
  from jaseci.prim.edge import Edge
6
6
  from jaseci.prim.node import Node
7
7
  from jaseci.jsorc.jsorc import JsOrc
@@ -52,18 +52,15 @@ class NodeTests(TestCaseHelper, TestCase):
52
52
  def test_add_entry_action_to_node_and_destroy(self):
53
53
  """Test connecting and disconnecting etc of nodes"""
54
54
  node1 = Architype(m_id=0, h=JsOrc.hook())
55
- act = action.Action(m_id=0, h=node1._h, name="yeah dude", value="SUP")
56
- node1.entry_action_ids.add_obj(act)
57
- self.assertEqual(
58
- node1.entry_action_ids.get_obj_by_name("yeah dude").value, "SUP"
59
- )
60
- self.assertEqual(len(node1.entry_action_ids), 1)
61
- self.assertTrue(node1.entry_action_ids.has_obj_by_name("yeah dude"))
62
- self.assertFalse(node1.entry_action_ids.has_obj_by_name("yeah dude"))
55
+ act = ability.Ability(m_id=0, h=node1._h, name="yeah dude")
56
+ node1.entry_ability_ids.add_obj(act)
57
+ self.assertEqual(len(node1.entry_ability_ids), 1)
58
+ self.assertTrue(node1.entry_ability_ids.has_obj_by_name("yeah dude"))
59
+ self.assertFalse(node1.entry_ability_ids.has_obj_by_name("yeah dude"))
63
60
 
64
- node1.entry_action_ids.destroy_obj_by_name(name="yeah dude")
65
- self.assertEqual(len(node1.entry_action_ids), 0)
66
- self.assertFalse(node1.entry_action_ids.has_obj_by_name("yeah dude"))
61
+ node1.entry_ability_ids.destroy_obj_by_name(name="yeah dude")
62
+ self.assertEqual(len(node1.entry_ability_ids), 0)
63
+ self.assertFalse(node1.entry_ability_ids.has_obj_by_name("yeah dude"))
67
64
 
68
65
  def test_adding_and_removing_from_hdnodes(self):
69
66
  """Test adding nodes and removing them from HDGDs"""
@@ -11,7 +11,7 @@ from jaseci.jsorc.jsorc import JsOrc
11
11
  from jaseci.jsorc.jsorc_utils import State
12
12
 
13
13
 
14
- class JacTests(TestCaseHelper, TestCase):
14
+ class ProgTests(TestCaseHelper, TestCase):
15
15
  """Unit tests for Jac language"""
16
16
 
17
17
  def setUp(self):
@@ -654,3 +654,18 @@ class JacTests(TestCaseHelper, TestCase):
654
654
  self.assertTrue(res["success"])
655
655
  self.assertTrue(res["report"], [None, None])
656
656
  self.assertIsNone(res.get("errors"))
657
+
658
+ def test_json_casting(self):
659
+ mast = JsOrc.master()
660
+ mast.sentinel_register(name="test", code=jtp.json_casting, auto_run="")
661
+
662
+ res = mast.general_interface_to_api(
663
+ api_name="walker_run",
664
+ params={"name": "json_casting", "ctx": {}},
665
+ )
666
+
667
+ self.assertTrue(res["success"])
668
+ self.assertEqual(
669
+ res["report"],
670
+ ['{"test": 1}', {"test2": 2}],
671
+ )
@@ -196,3 +196,25 @@ class StackTests(CoreTest):
196
196
  ret = self.call(self.smast, ["walker_run", {"name": "deep_except"}])
197
197
  self.assertTrue(ret["success"])
198
198
  self.assertIn("xxxx.xxxx", ret["report"][2]["msg"])
199
+
200
+ def test_dot_profiling_in_walker(self):
201
+ ret = self.call(
202
+ self.mast,
203
+ ["sentinel_register", {"code": self.load_jac("simple.jac")}],
204
+ )
205
+ ret = self.call(self.mast, ["walker_run", {"name": "init", "profiling": True}])
206
+ self.assertIn("digraph", ret["profile"]["graph"])
207
+ self.assertIn("jaseci", ret["profile"]["graph"])
208
+ self.assertGreater(len(ret["profile"]["graph"]), 1000)
209
+
210
+ def test_jac_profiling_in_walker(self):
211
+ ret = self.call(
212
+ self.mast,
213
+ ["sentinel_register", {"code": self.load_jac("simple.jac")}],
214
+ )
215
+ ret = self.call(
216
+ self.mast, ["walker_run", {"name": "complex", "profiling": True}]
217
+ )
218
+ print(ret["profile"]["jac"])
219
+ self.assertIn("cum_time", ret["profile"]["jac"])
220
+ self.assertIn("run_walker", ret["profile"]["graph"])
@@ -21,6 +21,8 @@ import time
21
21
  from .actions_state import ActionsState
22
22
 
23
23
  POLICIES = ["Default", "Evaluation"]
24
+ THRESHOLD = 0.2
25
+ NODE_MEM_THRESHOLD = 0.8
24
26
 
25
27
 
26
28
  class ActionsOptimizer:
@@ -42,6 +44,7 @@ class ActionsOptimizer:
42
44
  self.actions_calls = actions_calls
43
45
  self.policy_params = {}
44
46
  self.policy_state = {}
47
+ self.last_eval_configs = []
45
48
 
46
49
  def kube_create(self, config):
47
50
  kube = JsOrc.svc("kube").poke(cast=KubeService)
@@ -97,7 +100,8 @@ class ActionsOptimizer:
97
100
  def load_action_remote(self, name, unload_existing=False):
98
101
  """
99
102
  Load a remote action.
100
- JSORC will get the URL of the remote microservice and stand up a microservice if there isn't currently one in the cluster.
103
+ JSORC will get the URL of the remote microservice
104
+ and stand up a microservice if there isn't currently one in the cluster.
101
105
  Return True if the remote action is loaded successfully,
102
106
  False otherwise
103
107
  """
@@ -137,10 +141,12 @@ class ActionsOptimizer:
137
141
  Load an action module
138
142
  """
139
143
  cur_state = self.actions_state.get_state(name)
144
+ logger.info(cur_state)
140
145
  if cur_state is None:
141
146
  cur_state = self.actions_state.init_state(name)
142
147
 
143
148
  if cur_state["mode"] == "module":
149
+ logger.info("ALREADY A MODULE LOADED")
144
150
  # Check if there is already a local action loaded
145
151
  return
146
152
 
@@ -257,7 +263,6 @@ class ActionsOptimizer:
257
263
  return
258
264
  elif self.policy == "Evaluation":
259
265
  self._actionpolicy_evaluation()
260
-
261
266
  if len(self.actions_change) > 0:
262
267
  self.apply_actions_change()
263
268
 
@@ -276,9 +281,16 @@ class ActionsOptimizer:
276
281
  c = copy.deepcopy(con)
277
282
  c[act] = m
278
283
  if m == "local":
279
- c["local_mem"] += action_configs[act].get("remote_memory", 0)
280
- if c["local_mem"] < node_mem:
284
+ local_mem_requirement = action_configs[act][
285
+ "local_mem_requirement"
286
+ ]
287
+ c["local_mem"] = c["local_mem"] + local_mem_requirement
288
+ if c["local_mem"] < (node_mem * NODE_MEM_THRESHOLD):
281
289
  new_configs.append(dict(c))
290
+ else:
291
+ logger.info(
292
+ f"config dropped for memory constraint: {c},\n\tcurrent node memory: {node_mem}\n\tavailable memory: {(node_mem * NODE_MEM_THRESHOLD)-c['local_mem'] }"
293
+ )
282
294
  else:
283
295
  new_configs.append(dict(c))
284
296
  all_configs = list(new_configs)
@@ -300,8 +312,12 @@ class ActionsOptimizer:
300
312
  "cur_config": None, # current active configuration
301
313
  "remain_configs": [], # remaining configurations that need to be evaluated
302
314
  "past_configs": [], # configurations already evaluated
303
- "eval_phase": 10, # how long is evaluatin period (in seconds)
304
- "perf_phase": 100, # how long is the performance period (in seconds)
315
+ "eval_phase": self.policy_params.get(
316
+ "eval_phase", 10
317
+ ), # how long is evaluatin period (in seconds)
318
+ "perf_phase": self.policy_params.get(
319
+ "perf_phase", 100
320
+ ), # how long is the performance period (in seconds)
305
321
  "cur_phase": 0, # how long the current period has been running
306
322
  "prev_best_config": self.actions_state.get_all_state(),
307
323
  }
@@ -434,7 +450,6 @@ class ActionsOptimizer:
434
450
  policy_state["cur_phase"] = 0
435
451
  self.benchmark["active"] = True
436
452
  self.benchmark["requests"] = {}
437
-
438
453
  self.policy_state["Evaluation"] = policy_state
439
454
 
440
455
  def _get_action_change(self, new_action_state):
@@ -466,7 +481,7 @@ class ActionsOptimizer:
466
481
  # But this might change down the line
467
482
  for name, change_type in actions_change.items():
468
483
  logger.info(f"==Actions Optimizer== Changing {name} {change_type}")
469
- if change_type == "to_local" or change_type == "to_module":
484
+ if change_type in ["to_local", "_to_local", "_to_module", "to_module"]:
470
485
  # Switching from no action loaded to local
471
486
  self.load_action_module(name)
472
487
  del self.actions_change[name]