#WAIT inside of an async block hangs the interpreter
gerzytet opened this issue · 6 comments
for example, when I ran this in a synced named trigger:
r = 2
#MESSAGE "hi"
ASYNC
#MESSAGE "test"
#WAIT 1
#MESSAGE "test2"
r = 6
ENDASYNC
#MESSAGE "bye"
#MESSAGE r
the output was:
hi
bye
2
test
The async block ended at #WAIT
I also tried a version of that test script that waits for the async block to finish first, with the same result.
I think this issue occured because #WAIT Executor is illegal in SYNCed Trigger, even though we use ASYNC block.
In conclusion, ASYNC block got error on #WAIT and ended the block right there and continued trigger.
So It would be needed that #WAIT act as nothing if it is located in wrong direction.
(maybe #CANCELEVENT also have same issue)
@wysohn
I was poking around the Interpreter with a debugger while it was running the code sample
The problem is that it hangs the interpreter
You read that correctly. The interpreter hangs on the call to wait(), the code doesn't finish executing and the thread doesn't go away.
Run this a few times and look at the thread list.
@gerzytet
Good catch
Probably the notify() method is being used on the wrong thread since ASYNC would create a new thread while notify() is being used on the original interpreter thread.
@wysohn
do you have any ideas on what code needs to be fixed?
@gerzytet
https://github.com/wysohn/TriggerReactor/blob/3fec49022c2bbe0027e066f92c0c435a391d99e2/core/src/main/java/io/github/wysohn/triggerreactor/core/script/interpreter/Interpreter.java#L1119
This piece of code will be executed after the provided 'later' seconds later so that the thread which is executing the Interpreter would continue to work on the rest of the codes.
Probably something is not working as intended as we spawn a new thread for ASYNC.
It's Java's 'monitor' concept if you haven't heard of it. Interpreter use itself's instance as the monitor object when #WAIT is called.
Interpreter.this.waitFlag = false;
Interpreter.this.notify();
Yup. The problem is that Interpreter.this refers to the old interpreter.
when setExecutorMap is run, the WAIT executor gets replaced with the WAIT of the original interpreter. So Interpreter.this is bound to the wrong object.
The solution is to call initDefaultExecutors again after setExecutorMap. I'll fix it when I get home