|
@@ -21,6 +21,10 @@
|
|
self.source = None
|
|
self.source = None
|
|
self.port = int(sys.argv[1])
|
|
self.port = int(sys.argv[1])
|
|
self.count = 0
|
|
self.count = 0
|
|
|
|
+
|
|
|
|
+ self.debugged_users = set()
|
|
|
|
+ self.debug_info = {}
|
|
|
|
+ self.done_something = False
|
|
|
|
|
|
self.mvs_operations = {
|
|
self.mvs_operations = {
|
|
"CN": self.mvs.create_node,
|
|
"CN": self.mvs.create_node,
|
|
@@ -95,6 +99,8 @@
|
|
<script>
|
|
<script>
|
|
# No JSON encoding necessary, as it is not complex
|
|
# No JSON encoding necessary, as it is not complex
|
|
try:
|
|
try:
|
|
|
|
+ print 'from_mvi %s' % data
|
|
|
|
+ self.done_something = False
|
|
if data["op"] == "set_input":
|
|
if data["op"] == "set_input":
|
|
if "value" in data:
|
|
if "value" in data:
|
|
value = [json.loads(data["value"])]
|
|
value = [json.loads(data["value"])]
|
|
@@ -103,6 +109,34 @@
|
|
self.input_queue[data["username"]].append((source, value))
|
|
self.input_queue[data["username"]].append((source, value))
|
|
elif data["op"] == "get_output":
|
|
elif data["op"] == "get_output":
|
|
self.output_queue[data["username"]].append(source)
|
|
self.output_queue[data["username"]].append(source)
|
|
|
|
+ elif data["op"] == "attach_debugger":
|
|
|
|
+ self.debugged_users.add(data["username"])
|
|
|
|
+ self.done_something = True
|
|
|
|
+ self.source = source
|
|
|
|
+ self.debug_info[data["username"]] = {'state': 'running', 'breakpoints': []}
|
|
|
|
+ elif data["op"] == "detach_debugger":
|
|
|
|
+ self.debugged_users.discard(data["username"])
|
|
|
|
+ self.done_something = True
|
|
|
|
+ self.source = source
|
|
|
|
+ del self.debug_info[data["username"]]
|
|
|
|
+ elif data["op"] == "pause":
|
|
|
|
+ if data["username"] in self.debugged_users:
|
|
|
|
+ self.debug_info[data["username"]]['state'] = 'paused'
|
|
|
|
+ self.done_something = True
|
|
|
|
+ self.source = source
|
|
|
|
+ elif data["op"] == "resume":
|
|
|
|
+ if data["username"] in self.debugged_users:
|
|
|
|
+ self.debug_info[data["username"]]['state'] = 'running'
|
|
|
|
+ self.done_something = True
|
|
|
|
+ self.source = source
|
|
|
|
+ elif data["op"] == "step_over":
|
|
|
|
+ pass
|
|
|
|
+ self.done_something = True
|
|
|
|
+ self.source = source
|
|
|
|
+ elif data["op"] == "step_into":
|
|
|
|
+ pass
|
|
|
|
+ self.done_something = True
|
|
|
|
+ self.source = source
|
|
else:
|
|
else:
|
|
raise Exception("DROPPING unknown operation: " + str(data["op"]))
|
|
raise Exception("DROPPING unknown operation: " + str(data["op"]))
|
|
except ValueError:
|
|
except ValueError:
|
|
@@ -110,6 +144,15 @@
|
|
raise
|
|
raise
|
|
</script>
|
|
</script>
|
|
</transition>
|
|
</transition>
|
|
|
|
+
|
|
|
|
+ <transition cond="self.done_something" target=".">
|
|
|
|
+ <raise event="HTTP_input" scope="narrow" target="'to_mvi/%s' % self.source">
|
|
|
|
+ <parameter expr="json.dumps(True)"/>
|
|
|
|
+ </raise>
|
|
|
|
+ <script>
|
|
|
|
+ self.done_something = False
|
|
|
|
+ </script>
|
|
|
|
+ </transition>
|
|
</state>
|
|
</state>
|
|
</state>
|
|
</state>
|
|
|
|
|
|
@@ -121,37 +164,38 @@
|
|
self.destination = None
|
|
self.destination = None
|
|
if self.users:
|
|
if self.users:
|
|
user = self.users.pop()
|
|
user = self.users.pop()
|
|
-
|
|
|
|
- # Check if there are values to input
|
|
|
|
- if self.input_queue[user]:
|
|
|
|
- source, args = self.input_queue[user].pop(0)
|
|
|
|
- for args_entry in args:
|
|
|
|
- self.execute_modelverse(user, "set_input", [args_entry])
|
|
|
|
-
|
|
|
|
- self.destination = source
|
|
|
|
- self.value = "OK"
|
|
|
|
- self.all_failed = False
|
|
|
|
-
|
|
|
|
- # Now process for some steps, or until we are again blocked for input
|
|
|
|
- for x in xrange(100):
|
|
|
|
- self.execute_modelverse(user, "execute_rule", [])
|
|
|
|
-
|
|
|
|
- if not self.mvk.success:
|
|
|
|
- # Blocking or broken, so quit already to stop wasting CPU
|
|
|
|
- break
|
|
|
|
-
|
|
|
|
- # Could at least execute one instruction, so mark it as "not failed"
|
|
|
|
- self.all_failed = False
|
|
|
|
-
|
|
|
|
- # Check that we don't have anything to output yet, otherwise we wait
|
|
|
|
- if self.destination is None:
|
|
|
|
- # Perform output if there is anything
|
|
|
|
- if self.output_queue[user]:
|
|
|
|
- self.execute_modelverse(user, "get_output", [])
|
|
|
|
- if self.mvk.success:
|
|
|
|
- self.destination = self.output_queue[user].pop(0)
|
|
|
|
- self.value = self.mvk.returnvalue
|
|
|
|
- self.all_failed = False
|
|
|
|
|
|
+ if not user in self.debugged_users or self.debug_info[user]['state'] == 'running':
|
|
|
|
+ # Check if there are values to input
|
|
|
|
+ if self.input_queue[user]:
|
|
|
|
+ source, args = self.input_queue[user].pop(0)
|
|
|
|
+ for args_entry in args:
|
|
|
|
+ self.execute_modelverse(user, "set_input", [args_entry])
|
|
|
|
+
|
|
|
|
+ self.destination = source
|
|
|
|
+ self.value = "OK"
|
|
|
|
+ self.all_failed = False
|
|
|
|
+
|
|
|
|
+ nr_of_steps = 1 if user in self.debugged_users else 100
|
|
|
|
+ # Now process for some steps, or until we are again blocked for input
|
|
|
|
+ for x in xrange(nr_of_steps):
|
|
|
|
+ self.execute_modelverse(user, "execute_rule", [])
|
|
|
|
+
|
|
|
|
+ if not self.mvk.success:
|
|
|
|
+ # Blocking or broken, so quit already to stop wasting CPU
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ # Could at least execute one instruction, so mark it as "not failed"
|
|
|
|
+ self.all_failed = False
|
|
|
|
+
|
|
|
|
+ # Check that we don't have anything to output yet, otherwise we wait
|
|
|
|
+ if self.destination is None:
|
|
|
|
+ # Perform output if there is anything
|
|
|
|
+ if self.output_queue[user]:
|
|
|
|
+ self.execute_modelverse(user, "get_output", [])
|
|
|
|
+ if self.mvk.success:
|
|
|
|
+ self.destination = self.output_queue[user].pop(0)
|
|
|
|
+ self.value = self.mvk.returnvalue
|
|
|
|
+ self.all_failed = False
|
|
|
|
|
|
else:
|
|
else:
|
|
if self.count >= 2000:
|
|
if self.count >= 2000:
|