Closed anatoliykmetyuk closed 9 years ago
so as for now I'm using "; ..." as a replacement for "/ .." to test the actor example, since "/ .." will just trigger infinite activation
I added test cases such as [ a / .. ] to OperatorsSuite; these made the program hang. There was no output showing where the hanging was. Therefore I added a "-v" command line option for verbose output. Running the suite with " | more" we see that the "a" is activated a second time (and more, if we let "more" proceed":
>> 22 Continuation 4 / ... {2 Activation 4 / ..., 26 Deactivation 4 / ..., 25 Break 4 / ..., 4 / ...} 4 / S=false nActivated=2 (=0S+2N)
++ 27 Activation 12 a
So this points to CommonScriptExecutor.handleContinuation()
Fixed the issue (and about 5 more failing tests) For this purpose I added var aaActivated = false to N_n_ary_op. This is a bit messy, but a clean up has low priority FTTB.
OperatorsSuite was not strict enough. After I improved it, the process a b / ..
appeared to be spawning one a
too much after an a
had been processed from the input stream: the expected tokens were then a,a,b
instead of a,b
.
For the time being this should not be a showstopper IMO; x / ..
will in many cases work fine.
live = {println("x")} {println("y")} / ..
at certain point of time, leftmost node of the graph under "/" has Success and this success is also assigned to the rightmost node that is a "clone" of this node. This may happen due to non-referential comparison of case classes.
case class Foo(x: Int)
val x = Foo(3)
val y = Foo(3)
x == y // true
x eq y // false
Also:
live = {println("x")} / ..
here, after first node has success, "/" by itself has success without any continuation
I intend to really solve this issue now; I'll log my actions here so that others may learn how to tackle such problems (or how not to tackle).
OperatorsSuite now reports by default all failed tests, except when in silent mode (-s
). So:
build/pack/bin/scala subscript.test.OperatorsSuiteApp
test 330: a b/.. after input: a should expect: ab - Fails; expects: aab; already marked as FAIL
test 360: ./a b should expect: 1a - Fails; expects: a; already marked as FAIL
test 366: .|a b should expect: 1a - Fails; expects: a; already marked as FAIL
test 369: ./a b/./c d should expect: 1a - Fails; expects: ac; already marked as FAIL
test 564: (a;{**};b) ...||c ... after input: a should expect: bc - Fails; expects: c; already marked as FAIL
test 565: (a;{**};b) ...||c ... after input: ab should expect: ac - Fails; expects: c; already marked as FAIL
The interesting failed test has index 330. So we can run the test program with this index as a parameter. This gives all call graph messages, and when code fragments are about to be executed, the call graph is shown:
build/pack/bin/scala subscript.test.OperatorsSuiteApp 330
test 330: a b/.. after input: a should expect: ab
++ 1 Activation 3 <lambda>
-- 1 Activation 3 <lambda>
>> 1 Activation 3 <lambda>
++ 2 Activation 4 /
-- 2 Activation 4 /
>> 2 Activation 4 /
++ 3 Activation 5 ;
++ 4 Continuation 4 / {2 Activation 4 /, 5 ;} 4 / S=false nActivated=1 (=0S+1N)
-- 3 Activation 5 ;
>> 3 Activation 5 ;
++ 5 Activation 6 a
++ 6 Continuation 5 ; {3 Activation 5 ;, 6 a} 5 ; S=false nActivated=1 (=0S+1N)
-- 5 Activation 6 a
>> 5 Activation 6 a
...
>> 13 AAToBeExecuted 11 {??}
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=2 (=0S+2N)
* 5 ; S=false nActivated=1 (=0S+1N)
----*------------------------- 6 a
* 7 a
* 8 atom
* 9 atom
* 10 @:
---------*--------------------11 {??}
=== Messages ===
=== End ===
++ 30 AAExecutionFinished 11 {??}
...
Such tracing may often be helpful, but the current bug requires that we inspect the call graph at any message handling. For this we supply also the -V
flag, for "very verbose":
build/pack/bin/scala subscript.test.OperatorsSuiteApp -V 330
test 330: a b/.. after input: a should expect: ab
++ 1 Activation 3 <lambda>
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
=== Messages ===
1 Activation 3 <lambda>
=== End ===
-- 1 Activation 3 <lambda>
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
=== Messages ===
=== End ===
...
This yields a long list. Browse through it to see where the two subtrees with the a
scripts have been grown:
++ 112 Activation 33 {??}
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=5 (=0S+5N)
|* 5 ; S=false nActivated=2 (=1S+1N)
--|-*-------------------------13 b
| * 14 b
| * 15 atom
| * 16 atom
| * 17 @:
--|------*--------------------18 {??}
|* 19 ; S=false nActivated=1 (=0S+1N)
| * 20 a
| * 21 a
| * 22 atom
--|----*----------------------23 atom
| * 24 @:
| * 25 {??}
|* 27 ; S=false nActivated=1 (=0S+1N)
| * 28 a
--|--*------------------------29 a
| * 30 atom
| * 31 atom
| * 32 @:
| * 33 {??}
So this is where things must have already gone wrong. Now we go to the three places where the continuation messages for /...
were handled; the first of which that did not lead to a new a
branch, whereas the other two did.
The handling of continuation messages stand out in the log because of relatively long listings of attribute values. The handling of /...
stand out even more since these listings have double size. There is a "finally" part, and an A+...+G part; these listings are created in trait ContinuationHandler
.
At the end of these loggings there may be a line such as ++ 77 Activation 19 ;
, indicating that another node is activated as a result of handling the Continuation message.
>> 25 Continuation 4 / ... {2 Activation 4 / ..., 29 Deactivation 4 / ..., 28 Break 4 / ..., 4 / ...} 4 / S=false nActivated=2 (=0S+2N)
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=2 (=0S+2N)
* 5 ; S=false nActivated=1 (=0S+1N)
----*------------------------- 6 a
* 7 a
* 8 atom
* 9 atom
* 10 @:
---------*--------------------11 {??}
=== Messages ===
13 AAToBeExecuted 11 {??}
=== End ===
F:
activationMode: Optional
hadFullBreak: false
nActivatedMandatoryChildren: 2
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 2
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: -1
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: false
Finally:
activationMode: Optional
hadFullBreak: false
nActivatedMandatoryChildren: 2
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 2
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: -1
indexChild_marksPause: 12
aaActivated: true
aaActivated_optional: false
activateNext: false
activationEnded: false
activationEndedOptionally: false
shouldSucceed: false
and
>> 42 Continuation 4 / ... {73 AAActivated 4 / ..., 41 AAHappened 4 / ..., 4 / ...} 4 / S=false nActivated=2 (=0S+2N)
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=2 (=0S+2N)
* 5 ; S=false nActivated=2 (=1S+1N)
----*-------------------------13 b
* 14 b
* 15 atom
* 16 atom
* 17 @:
---------*--------------------18 {??}
=== Messages ===
66 AAToBeExecuted 18 {??}
=== End ===
Finally:
activationMode: Active
hadFullBreak: false
nActivatedMandatoryChildren: 2
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 2
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: 12
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: false
activateNext: true
activationEnded: false
activationEndedOptionally: false
shouldSucceed: false
++ 77 Activation 19 ;
and
>> 78 Continuation 4 / ... {-1 Activation 4 / ..., 94 AAActivated 4 / ..., 4 / ...} 4 / S=false nActivated=3 (=0S+3N)
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=3 (=0S+3N)
|* 5 ; S=false nActivated=2 (=1S+1N)
--|-*-------------------------13 b
| * 14 b
| * 15 atom
| * 16 atom
| * 17 @:
--|------*--------------------18 {??}
|* 19 ; S=false nActivated=1 (=0S+1N)
| * 20 a
| * 21 a
| * 22 atom
--|----*----------------------23 atom
| * 24 @:
| * 25 {??}
=== Messages ===
66 AAToBeExecuted 18 {??}
87 AAToBeExecuted 25 {??}
=== End ===
C:
activationMode: Active
hadFullBreak: false
nActivatedMandatoryChildren: 3
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 3
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: 12
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: true
Finally:
activationMode: Active
hadFullBreak: false
nActivatedMandatoryChildren: 3
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 3
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: 12
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: true
activateNext: true
activationEnded: false
activationEndedOptionally: false
shouldSucceed: false
++ 98 Activation 26 ..
and
>> 99 Continuation 4 / ... {-1 Activation 4 / ..., 103 Deactivation 4 / ..., 102 Break 4 / ..., 4 / ...} 4 / S=false nActivated=4 (=0S+4N)
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=4 (=0S+4N)
|* 5 ; S=false nActivated=2 (=1S+1N)
--|-*-------------------------13 b
| * 14 b
| * 15 atom
| * 16 atom
| * 17 @:
--|------*--------------------18 {??}
|* 19 ; S=false nActivated=1 (=0S+1N)
| * 20 a
| * 21 a
| * 22 atom
--|----*----------------------23 atom
| * 24 @:
| * 25 {??}
=== Messages ===
66 AAToBeExecuted 18 {??}
87 AAToBeExecuted 25 {??}
=== End ===
E:
activationMode: Optional
hadFullBreak: false
nActivatedMandatoryChildren: 4
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 4
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: 12
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: true
Finally:
activationMode: Active
hadFullBreak: false
nActivatedMandatoryChildren: 4
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 4
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: -1
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: false
activateNext: true
activationEnded: false
activationEndedOptionally: false
shouldSucceed: false
++ 104 Activation 27 ;
and
>> 105 Continuation 4 / ... {-1 Activation 4 / ..., 121 AAActivated 4 / ..., 4 / ...} 4 / S=false nActivated=5 (=0S+5N)
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=5 (=0S+5N)
|* 5 ; S=false nActivated=2 (=1S+1N)
--|-*-------------------------13 b
| * 14 b
| * 15 atom
| * 16 atom
| * 17 @:
--|------*--------------------18 {??}
|* 19 ; S=false nActivated=1 (=0S+1N)
| * 20 a
| * 21 a
| * 22 atom
--|----*----------------------23 atom
| * 24 @:
| * 25 {??}
|* 27 ; S=false nActivated=1 (=0S+1N)
| * 28 a
--|--*------------------------29 a
| * 30 atom
| * 31 atom
| * 32 @:
| * 33 {??}
=== Messages ===
66 AAToBeExecuted 18 {??}
87 AAToBeExecuted 25 {??}
114 AAToBeExecuted 33 {??}
=== End ===
C:
activationMode: Active
hadFullBreak: false
nActivatedMandatoryChildren: 5
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 5
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: -1
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: false
Finally:
activationMode: Active
hadFullBreak: false
nActivatedMandatoryChildren: 5
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 5
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: -1
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: false
activateNext: true
activationEnded: false
activationEndedOptionally: false
shouldSucceed: false
++ 125 Activation 34 ..
and
>> 126 Continuation 4 / ... {-1 Activation 4 / ..., 130 Deactivation 4 / ..., 129 Break 4 / ..., 4 / ...} 4 / S=false nActivated=6 (=0S+6N)
------------------------------ 1 ** S=false nActivated=1 (=0S+1N)
* 2 <root>
* 3 <lambda>
* 4 / S=false nActivated=6 (=0S+6N)
|* 5 ; S=false nActivated=2 (=1S+1N)
--|-*-------------------------13 b
| * 14 b
| * 15 atom
| * 16 atom
| * 17 @:
--|------*--------------------18 {??}
|* 19 ; S=false nActivated=1 (=0S+1N)
| * 20 a
| * 21 a
| * 22 atom
--|----*----------------------23 atom
| * 24 @:
| * 25 {??}
|* 27 ; S=false nActivated=1 (=0S+1N)
| * 28 a
--|--*------------------------29 a
| * 30 atom
| * 31 atom
| * 32 @:
| * 33 {??}
=== Messages ===
66 AAToBeExecuted 18 {??}
87 AAToBeExecuted 25 {??}
114 AAToBeExecuted 33 {??}
=== End ===
F:
activationMode: Optional
hadFullBreak: false
nActivatedMandatoryChildren: 6
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 6
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: -1
indexChild_marksPause: -1
aaActivated: true
aaActivated_optional: false
Finally:
activationMode: Optional
hadFullBreak: false
nActivatedMandatoryChildren: 6
nActivatedMandatoryChildrenWithSuccess: 0
nActivatedMandatoryChildrenWithoutSuccess: 6
nActivatedOptionalChildren: 0
nActivatedOptionalChildrenWithSuccess: 0
nActivatedOptionalChildrenWithoutSuccess: 0
indexChild_marksOptionalPart: -1
indexChild_marksPause: 34
aaActivated: true
aaActivated_optional: false
activateNext: false
activationEnded: false
activationEndedOptionally: false
shouldSucceed: false
The latter one does not activate a new node in the call graph; hence the cycle ends here.
This comment has grown very large; time to leave it like this. In the next comment I will analyse the /...
Continuation message handlings.
To summarize: the following are indexes of continuation messages, together with the branches these take.
25 - branch F, no further activation
42 - no explicit branch (will be H), activate ;
78 - branch C, activate ..
99 - branch E, activate ;
<< this should not have happened
105 - branch C, activate ..
126 - branch F, no further activation
It looks like it has been really fixed now: https://github.com/AndreVanDelft/scala/commit/06257608764c14c3ca12883df754c3e69697b1fe
As for now, "/ .." seems not to break activation. Observe the following script in the debugger: