Bug #2795
Bug #2677: fix drawing and functional differences between P2J GUI and 4GL GUI
scoped variables/tables/etc and persistent procedures
100%
History
#1 Updated by Constantin Asofiei over 8 years ago
There is a new feature in GUI code which doesn't exist in P2J: if program A defines something NEW SHARED and is ran persistent, this data is visible to any other program B executed from within A's body (via let's say an internal procedure in A).
Currently, I think any shared data which is created within program A gets destroyed when A's external procedure is finished. We need some support to save this data and restore it when some internal procedure or function in A is ran.
#2 Updated by Constantin Asofiei over 8 years ago
- % Done changed from 0 to 100
- Target version set to Milestone 12
- Status changed from New to WIP
The solution is in branch 2677a rev 10969.
The fix required to save the scoped data in SharedVariableManager and push/pop it each time a persistent procedure's internal entry is executed.
A testcases which shows this is uast/procedures/shared_data_a.p
, uast/procedures/shared_data_b.p
and uast/procedures/shared_data_run.p
.
#3 Updated by Greg Shah over 8 years ago
Code Review Task Branch 2677a Revision 10969
I'm good with the changes, but have one area in which I'm confused.
SVM.scopeFinished()
uses mainwa.shared.getDictionaryAtScope(0, false);
to add resources for persistent external procedures.
SVM.scopeDeleted()
uses mainwa.shared.getDictionaryAtScope(gscope, true)
where gscope = mainwa.shared.size() - 1
.
It is not clear to me why it is safe to assume that these will always refer to the same scope.
#4 Updated by Constantin Asofiei over 8 years ago
Greg Shah wrote:
Code Review Task Branch 2677a Revision 10969
I'm good with the changes, but have one area in which I'm confused.
SVM.scopeFinished()
usesmainwa.shared.getDictionaryAtScope(0, false);
to add resources for persistent external procedures.
Non GLOBAL SHARED resources are added to the current scope - so this saves the current scope, for the persistent procedure being exited.
SVM.scopeDeleted()
usesmainwa.shared.getDictionaryAtScope(gscope, true)
wheregscope = mainwa.shared.size() - 1
.
Ah, now I see it... what I wanted to do is remove any GLOBAL SHARED defined in the persistent procs, from the global scope. but I don't think this works properly, as these are not saved in the current scope, anyway.
I'll do some more testing
#5 Updated by Greg Shah over 8 years ago
Did you put the final changes in for this one? Can this be closed?
#6 Updated by Constantin Asofiei over 8 years ago
Greg Shah wrote:
Did you put the final changes in for this one? Can this be closed?
No, haven't got the chance to finish it. Will do after #2809
#7 Updated by Constantin Asofiei over 8 years ago
There is another issue here, for DEFINE NEW GLOBAL SHARED TEMP-TABLE
: if there already exists a declaration for the same temp-table, then the statement must be treated as DEFINE SHARED TEMP-TABLE
. Currently P2J converts this to:
Tt21_1.Buf tt2 = TemporaryBuffer.define(Tt21_1.Buf.class, "tt2", "tt2", false); public void execute() { externalProcedure(new Block() { public void body() { RecordBuffer.openScope(tt2); SharedVariableManager.addTempTable(ScopeLevel.GLOBAL, "tt2", tt2);
So, regardless if I check if the temp-table is already globally defined,
tt2
field in the java code is already assigned (and a temp-table created, when is not needed).
This needs to be converted to something else... maybe something like for the example above, and don't call TemporaryBuffer.define
unless this is the first definition of this temp-table as GLOBAL:
Tt21_1.Buf tt2 = SharedVariableManager.addTempTable(ScopeLevel.GLOBAL, "tt2", Tt21_1.Buf.class, "tt2", "tt2", false);
#8 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
There is another issue here, for
DEFINE NEW GLOBAL SHARED TEMP-TABLE
: if there already exists a declaration for the same temp-table, then the statement must be treated asDEFINE SHARED TEMP-TABLE
. Currently P2J converts this to:
[...]
So, regardless if I check if the temp-table is already globally defined,tt2
field in the java code is already assigned (and a temp-table created, when is not needed).This needs to be converted to something else... maybe something like for the example above, and don't call
TemporaryBuffer.define
unless this is the first definition of this temp-table as GLOBAL:
[...]
Your initial solution seems to be runtime-only, but it seems now you are discussing a conversion issue. Or have I misunderstood your statement, "This needs to be converted to something else..."? Do you mean that the purpose of TemporaryBuffer.define
has to be changed/converted to something else, based on which temp-table resources exist on the stack at the time it is invoked? Or are you suggesting a change to static conversion? If the latter, I'm not sure how that would work.
#9 Updated by Constantin Asofiei over 8 years ago
Eric Faulhaber wrote:
Your initial solution seems to be runtime-only, but it seems now you are discussing a conversion issue.
Yes, this is a new conversion issue as a DEFINE NEW GLOBAL SHARED TEMP-TABLE
sometimes needs to be treated as DEFINE SHARED TEMP-TABLE
, if the table is already defined globally by someone else. See SVM.addVariable
- it has this code:
if (scope == ScopeLevel.GLOBAL) { T current = (T) wa.shared.getSymbolAtScope(name, -1); // ignore repeated global definitions if (current != null) { return current; } }
which checks the global registry for the var name - and return that if it exists. Otherwise, it defaults to registering the variable into the global scope. We need a similar approach for the temp-tables.
Or have I misunderstood your statement, "This needs to be converted to something else..."? Do you mean that the purpose of
TemporaryBuffer.define
has to be changed/converted to something else, based on which temp-table resources exist on the stack at the time it is invoked? Or are you suggesting a change to static conversion? If the latter, I'm not sure how that would work.
The converted code should be something like this:
Tt21_1.Buf tt2 = SharedVariableManager.addTempTable(ScopeLevel.GLOBAL, "tt2", Tt21_1.Buf.class, "tt2", "tt2"); public void execute() { externalProcedure(new Block() { public void body() { RecordBuffer.openScope(tt2); // this one will not be emitte: SharedVariableManager.addTempTable(ScopeLevel.GLOBAL, "tt2", tt2);
The
SVM.addTempTable
will check the global scope (if there is another temp-table with the same name) and return that, if it exists. Otherwise, use TemporaryBuffer.define
to create the temp-table and register it in the global scope.
I need to do some tests if the table definition does not match (different field count/types, indexes, etc), for the second DEFINE NEW GLOBAL SHARED TEMP-TABLE
.
#10 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
The
SVM.addTempTable
will check the global scope (if there is another temp-table with the same name) and return that, if it exists. Otherwise, useTemporaryBuffer.define
to create the temp-table and register it in the global scope.
OK, I see. So, the determination of whether to create/define the new, global temp-table would be made at runtime. My concern was that we wouldn't have enough information to do this at conversion time.
I need to do some tests if the table definition does not match (different field count/types, indexes, etc), for the second
DEFINE NEW GLOBAL SHARED TEMP-TABLE
.
Note that the logic which does this during conversion is a bit complicated and is being considered for change, due to concerns Stanislav raised w.r.t. browse. See #2564 (around note 216) and #2595. I'm adding Ovidiu as a watcher, since he architected the new DMO class/interface hierarchy for temp-tables.
Whatever the outcome of that rework, static conversion should already have determined whether the Progress compiler would consider any shared temp-tables defined in separate procedures as the same entity or not. What additional concerns do you have for this at runtime?
#11 Updated by Constantin Asofiei over 8 years ago
Guys, is the blockDepth
parameter in this TemporaryBuffer.define
API ever emitted?
public static <T extends Temporary> T define(Class<T> dmoBufIface, String variable, String legacyName, boolean global, boolean undoable, int blockDepth)
#12 Updated by Constantin Asofiei over 8 years ago
Eric Faulhaber wrote:
What additional concerns do you have for this at runtime?
In GLOBAL case: for temp-tables, if the table's schema does not match with the already shared version, then this errors occurs:
In procedure shared_data_d.p, shared temp-table tt2 has a conflict in field, index or undo status. (2075)
For variables, this error is shown:
shared_data_d.p Conflict in extent, datatype or undo status for global ch. (390)
We should implement these checks at runtime.
#13 Updated by Ovidiu Maxiniuc over 8 years ago
Constantin Asofiei wrote:
Guys, is the
blockDepth
parameter in thisTemporaryBuffer.define
API ever emitted?
[...]
Apparently, no. I was not able to find any reference in the conversion and neither at runtime (except for the internal calls, having -1
as default value for that parameter).
#14 Updated by Constantin Asofiei over 8 years ago
Ovidiu, please describe what this change in variable_definition.rules
tried to solve:
** 051 OM 20141203 Added double-initialization check for NEW SHARED GLOBAL EXTENT-s.
#15 Updated by Ovidiu Maxiniuc over 8 years ago
IIRC, there was an issue when using initialized shared variables, something like this:
Procedure p1:
DEFINE NEW SHARED GLOBAL VARIABLE a AS INT EXTENT 2 INIT 1. a[1] = 2. MESSAGE a[1]. RUN p2. MESSAGE a[1].
Procedure p2:
DEFINE SHARED GLOBAL VARIABLE a AS INT EXTENT INIT 1. MESSAGE a[1].
This printed:
2
1
1
instead of
2
2
2
because the extent variable
a
was automatically initialized a second time in p2
.The new code collects the variables that were created and not yet INITed and, after first (and only) initialization they are dropped from the collection so, when the second procedure is called the re-initialization is simply skipped.
#16 Updated by Constantin Asofiei over 8 years ago
Ovidiu Maxiniuc wrote:
OK, so the code is related to this: if aIIRC, there was an issue when using initialized shared variables, something like this:
...
because the extent variablea
was automatically initialized a second time inp2
.
The new code collects the variables that were created and not yet INITed and, after first (and only) initialization they are dropped from the collection so, when the second procedure is called the re-initialization is simply skipped.
NEW GLOBAL SHARED
var (extent or not) is already defined (NEW GLOBAL SHARED
or NEW SHARED
), then it must use that, and bypass the initialization code. This applies to temp-tables/buffers too.There are two problems here:
- the conditional code must emit for implicit initialization of extent vars, too.
- the conversion code is broken, the
init_global_shared_extents
snippet fromjava_templates.tpl
is not emitted correctly (thenew BDT[]
array is emitted at the SVM.addVariable, not in the inner block.
#17 Updated by Constantin Asofiei over 8 years ago
In regard to notes 15 and 16: I'm moving the initializer code for DEFINE NEW [GLOBAL] SHARED VARIABLE ... EXTENT ... INIT
as a parameter for SharedVariableManager.addVariable
as initializing the GLOBAL SHARED
var is a runtime decision, not conversion. Also, this will solve both issues in note 16, and will reduce the code footprint, as the assignMulti
calls will no longer be emitted for NEW SHARED
vars.
#18 Updated by Constantin Asofiei over 8 years ago
- the GLOBAL SHARED resources are not removed when the procedure gets deleted
- reworked shared extent var conversion
- reworked shared temp-table conversion
- fixed matching of shared vars, when a DEF SHARED or DEF NEW GLOBAL SHARED matches a variable in the current registry (it must match by type, etc).
- fixed resize of extent shared vars (the shared dictionary must update the reference).
- NO-UNDO matching for shared variables (this should be emitted as yet another parameter for the
SharedVariableManager.addVariable
). - if the shared var type doesn't match, raise an exception which will be caught by ControlFlowOps and transformed into an ERROR and raised to the caller in which the RUN statement is executed.
- matching for BUFFER, TEMP-TABLE, FRAME, MENU resources (as these are the currently SHARED resources supported by P2J).
Ovidiu: can you post some details about how the TEMP-TABLEs should be matched? Is there some existing code which checks this? This needs to be done at runtime.
#19 Updated by Ovidiu Maxiniuc over 8 years ago
Ovidiu: can you post some details about how the TEMP-TABLEs should be matched? Is there some existing code which checks this? This needs to be done at runtime.
At this moment, there is virtually no runtime code for matching TEMP-TABLEs. All work is done at conversion time, the DMO classes and buffer variables are generated to make sure the code works (at least from the POV of compiler).
Previous work was done as part of #2595 task. The results of my research for matching tables are gathered in notes 5, 6, 8, 12.
#20 Updated by Greg Shah over 8 years ago
I'm moving the initializer code for DEFINE NEW [GLOBAL] SHARED VARIABLE ... EXTENT ... INIT as a parameter for SharedVariableManager.addVariable as initializing the GLOBAL SHARED var is a runtime decision, not conversion.
Did you use lambdas for this?
#21 Updated by Constantin Asofiei over 8 years ago
Greg Shah wrote:
I'm moving the initializer code for DEFINE NEW [GLOBAL] SHARED VARIABLE ... EXTENT ... INIT as a parameter for SharedVariableManager.addVariable as initializing the GLOBAL SHARED var is a runtime decision, not conversion.
Did you use lambdas for this?
Not yet, but I'll switch both the extent initialization and the global shared temp-table definition to lambda exprs once I've found all the behaviour.
#22 Updated by Constantin Asofiei over 8 years ago
I've rebased 2795a from trunk rev 10960. As of rev 10966, what is missing is support for FRAME and MENU resources.
I'm planning to cleanup the code, document it and run conversion for GUI+server and full MAJIC regression testing.
If these pass, I would like to run a set of full customer tests - there are lots of changes in conversion/runtime. Ovidiu/Eric, can you help?
Finally, about shared temp-tables and extent fields: there is a new issue which is (I think) outside of the scope of this task. Consider a master (new shared) temp-table with an extent fieldf1
of 2. A slave (shared) temp-table is defined with field f1
extent of 3. When going back to the master temp-table, accessing index 3 directly is not possible, but is possible via the ::
dereference operator. The issues here:
- P2J doesn't support
h::f1(3)
construct (theDereferenceable
interface doesn't have APIs with the array index). - in the slave temp-table, the
TemporaryBuffer.useShared
will return the masterTemporary
instance - and this will limit the extent to 2... the slave temp-table is losing all its custom extent information (and maybe others, related to indexes, labels, etc).
#23 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
If these pass, I would like to run a set of full customer tests - there are lots of changes in conversion/runtime. Ovidiu/Eric, can you help?
Yes, I'll set up an environment to convert with 2795a/10966. Let me know if you make further changes based on the outcome of your tests, such that I need to convert again.
#24 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
Finally, about shared temp-tables and extent fields: there is a new issue which is (I think) outside of the scope of this task. Consider a master (new shared) temp-table with an extent fieldf1
of 2. A slave (shared) temp-table is defined with fieldf1
extent of 3. When going back to the master temp-table, accessing index 3 directly is not possible, but is possible via the::
dereference operator. The issues here:
- P2J doesn't support
h::f1(3)
construct (theDereferenceable
interface doesn't have APIs with the array index).- in the slave temp-table, the
TemporaryBuffer.useShared
will return the masterTemporary
instance - and this will limit the extent to 2... the slave temp-table is losing all its custom extent information (and maybe others, related to indexes, labels, etc).
Please create a separate issue for this. If you have test cases which show the expected outcome in Progress, please include them.
#25 Updated by Constantin Asofiei over 8 years ago
2795a rev 10967 is a good candidate for review (there are some javadocs missing and some TODO's in appserver invocation, which I haven't checked yet, but besides those it should be OK).
I've started (on devsrv01) GUI/server conversion + MAJIC full testing (conv + runtime).
Eric Faulhaber wrote:
Yes, I'll set up an environment to convert with 2795a/10966. Let me know if you make further changes based on the outcome of your tests, such that I need to convert again.
There are no other conversion changes in 10967.
#26 Updated by Constantin Asofiei over 8 years ago
Unfortunately GUI and server conversion both failed with a NPE. I'm looking into it.
#27 Updated by Constantin Asofiei over 8 years ago
Constantin Asofiei wrote:
Unfortunately GUI and server conversion both failed with a NPE. I'm looking into it.
I forgot to check support for shared non-temp-table buffers. I need to fix this before going into conversion testing.
#28 Updated by Constantin Asofiei over 8 years ago
2795a rev 10968 fixes the conversion issue about non-tt shared buffers. I'm running conversion again (will let you know if it passes).
#29 Updated by Constantin Asofiei over 8 years ago
- the message displayed when shared var does not exist (
Shared variable %s has not yet been created
) is incorrect in P2J - there is a case where an extent var, instead of being defined 43 (as this is how is defined in the
NEW SHARED
), is set to 34 in the shared var. P2J fails correctly... this looks like a typo in the program where lookup fails (is defined asSHARED
with extent 34). I think one of these changes might have been made after switching to P2J runtime, and it wasn't tested in the legacy system.
Also, there are changes in the MAJIC srcnew/java
code, where shared variables are used - I'll create a separate task for these.
Eric: You can start the Server conversion, the issues above will not affect it.
#30 Updated by Constantin Asofiei over 8 years ago
Ovidiu/Eric: something else to discuss. If an external program instantiation fails (for example, because a shared var can not be found), then we need to clean up after any other NEW SHARED
resources which were defined BEFORE the point of failure. Currently, these are saved in the SharedVariableManager$WorkArea.pending
map, which gets processed when the next scope is started.
I've added code to ControlFlowOps
to clean this pending
map if external program instantiation fails, but I'm not sure what I need to explicitly clean for NEW SHARED BUFFER
and NEW SHARED TEMP-TABLE
. I don't think is enough to just "lose" the reference from the pending
map, we might need to simulate a "delete" on these. Any ideas what I should keep an eye on, to ensure any "pending" buffer/temp-table is cleaned up? In BufferManager, RecordBuffer, etc?
#31 Updated by Constantin Asofiei over 8 years ago
In regard to note 30 - an idea would be to simulate an empty execute()
block, which will go through the scope start/end processing for all Scopeable
implementations... this would save us doing things explicitly and will allow the resources to be "cleaned" naturally. Although some special handling might be required for NEW GLOBAL SHARED
, as these are not saved in the "pending" map.
#32 Updated by Ovidiu Maxiniuc over 8 years ago
Constantin Asofiei wrote:
In regard to note 30 - an idea would be to simulate an empty
execute()
block, which will go through the scope start/end processing for allScopeable
implementations... this would save us doing things explicitly and will allow the resources to be "cleaned" naturally. Although some special handling might be required forNEW GLOBAL SHARED
, as these are not saved in the "pending" map.
Indeed, that would be an idea. I believe that forcing an 'execute' would cost a little CPU, but since this happens only on exception cases, the cost is negligible overall.
I guess imagined the use of a temporary variable like this:
public void execute() { Block block; try { block = Block() { [...] }; } catch (...) { block = emptyBodyBlockInstance; } externalProcedure(block); }
Just a thought, we could split the creation of the variable into declaration and initialization in init()
method and catch eventual initialization exceptions there and then handle them. The generated code wouldn't be affected.
#33 Updated by Constantin Asofiei over 8 years ago
Ovidiu Maxiniuc wrote:
Constantin Asofiei wrote:
In regard to note 30 - an idea would be to simulate an empty
execute()
block, which will go through the scope start/end processing for allScopeable
implementations... this would save us doing things explicitly and will allow the resources to be "cleaned" naturally. Although some special handling might be required forNEW GLOBAL SHARED
, as these are not saved in the "pending" map.Indeed, that would be an idea. I believe that forcing an 'execute' would cost a little CPU, but since this happens only on exception cases, the cost is negligible overall.
I guess imagined the use of a temporary variable like this:
I don't want to complicate the converted code. I'm thinking just calling something like this, directly from SharedVariableManager
(or ControlFlowOps
, not sure yet):
externalProcedure(new Block(){});
and it just hit me... there is no "external program" instance, as instantiation failed. But it might work just pushing a
new Object()
as the "currently executing external program", to have a THIS-PROCEDURE surrogate. And also there might need some other state from ControlFlowOps to be pushed.
Another reason to do this is there might be state from non-shared temp-tables, buffers, etc which need to be cleaned up, and these are not explicitly tracked.
#34 Updated by Greg Shah over 8 years ago
Code Review Task Branch 2795a Revision 10971
The changes are quite good.
Eric: Please review this ASAP.
1. Agent
and SharedVariableManager
need a history entries.
2. I prefer not to add child class references to BaseDataType
in initializeDefaultExtent()
. Can't we use a protected method that has a default implementating in BDT to provide the ctor
and arg
?
3. Several of the SharedVariableManager.addTempTable()
variants are missing javadoc.
#35 Updated by Eric Faulhaber over 8 years ago
Code review 2795a/10971:
In addition to Greg's comments above, please note the following:
Where you check for the TEMP_TABLE token type in TRPL rules, please check for WORK_TABLE as well, since this older syntax supports shared tables.
I am a little concerned about promoting all shared temp-tables to instance fields. Please make sure this does not invalidate the assumptions in buffer_name_conflicts.rules
, particularly w.r.t. my changes in rev 10851.
Can a persist.*
wildcard import statement be used in SharedVariableManager
?
#36 Updated by Eric Faulhaber over 8 years ago
I ran the cut-down search unit tests. Every API invoked produced the following error in the server and client logs (reported as SEVERE in the server.log):
Invalid or inappropriate handle value given to DELETE OBJECT or DELETE PROCEDURE statement. (5425)
However, all the tests passed, so perhaps this is an issue during cleanup which does not affect the XML output and/or temp-table results analyzed by the tests.
There is no stack trace or other useful information in the logs. I have not run any of the larger test sets yet.
#37 Updated by Constantin Asofiei over 8 years ago
Eric Faulhaber wrote:
Where you check for the TEMP_TABLE token type in TRPL rules, please check for WORK_TABLE as well, since this older syntax supports shared tables.
Thanks, only record_scoping.rules
needed a check for WORK_TABLE. buffer_definition.rules
already handles this with the etype
var.
I am a little concerned about promoting all shared temp-tables to instance fields. Please make sure this does not invalidate the assumptions in
buffer_name_conflicts.rules
, particularly w.r.t. my changes in rev 10851.
I think the trunk P2J already converts shared buffers/temp-tables to instance fields. More, temp-tables (shared or not) and shared buffers can be defined only in the external program, they can not be defined in procedures/functions. I've checked what happens in P2J if a buffer with the same name as a shared one is defined in an internal procedure, and in the converted code is disambiguated to a dedicate var scoped to the internal procedure. So I don't think there are issues related to name conflicts.
Can a
persist.*
wildcard import statement be used inSharedVariableManager
?
Yes, I've fixed it.
#38 Updated by Constantin Asofiei over 8 years ago
Greg Shah wrote:
1.
Agent
andSharedVariableManager
need a history entries.
Fixed in 10975
2. I prefer not to add child class references to
BaseDataType
ininitializeDefaultExtent()
. Can't we use a protected method that has a default implementating in BDT to provide thector
andarg
?
See 10973 - I've added a BDT.instantiateDefaultExtent()
which gets the default value for extent vars. It is overridden as needed, otherwise it just returns the variables' default initialization value.
3. Several of the
SharedVariableManager.addTempTable()
variants are missing javadoc.
Fixed in 10975.
So, what is left as of rev 10975:- resource cleanup (shared and non-shared) if external program instantiation fails
- the handle-related message Eric posted in note 36
#39 Updated by Constantin Asofiei over 8 years ago
I've rebased 2795a from trunk rev 10961 (new rev 10976).
Rev 10977 fixes another NPE related to shared frame check (widget format). Runtime testing restarted.
#40 Updated by Constantin Asofiei over 8 years ago
2795a rev 10978 adds logging to HandleOps.invalidDelete(handle)
. To enable it, add this node to directory.xml
's logging/loggers
section:
<node class="string" name="com.goldencode.p2j.util.HandleOps"> <node-attribute name="value" value="FINE"/> </node>
#41 Updated by Constantin Asofiei over 8 years ago
2795a rev 10979 adds instantiateDefaultExtent() to recid.
#42 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
2795a rev 10978 adds logging to
HandleOps.invalidDelete(handle)
. To enable it, add this node todirectory.xml
'slogging/loggers
section:
[...]
I've enabled the logging and run the cut-down search tests with 2795a/10979. All tests pass. Server log is attached to #1868-77.
#43 Updated by Eric Faulhaber over 8 years ago
I've run the full search tests. Functionally, the results are pretty good (other than the inappropriate handle issue reported in note 36 above, which seems to occur for every API call). However, there is a severe performance regression. The run normally takes 80-90 minutes, but with 2795a/10979, it took more than 10 hours. I don't know if the regression is in the 2795a branch, or in the 2332a branch, which was merged to trunk rev. 10961, because I didn't run the unit tests for that branch myself. I'll re-run the tests with trunk 10961 to further isolate the issue.
I did a bit of profiling while the tests were running, and we seem to be spending an inordinate amount of time in the Text.deepAssign
method, invoked when new character
objects are constructed by DMOs. Since the code for that method was not changed in this branch, it seems that something changed to cause the DMO getter methods to be invoked far more often than before. I haven't analyzed beyond that yet.
We had no new test failures, however there were 6 new test timeout errors. Results and logs are posted in #1868-78.
#44 Updated by Eric Faulhaber over 8 years ago
Eric Faulhaber wrote:
I'll re-run the tests with trunk 10961 to further isolate the issue.
This run was normal (~75 minutes), so the performance regression is in the changes specific to the 2795a branch. Not sure if it's related to the inappropriate handle error, but I suspect not, since it seems to be related to DMO use.
#45 Updated by Constantin Asofiei over 8 years ago
I think the reason is related to this issue: all buffers created for a temp-table must be deleted if the temp-table gets deleted.
Also, there is another issue: if a NEW GLOBAL SHARED
is resolved to an existing temp-table, then it must create another buffer for it, and not re-use the default-buffer for the temp-table.
#46 Updated by Constantin Asofiei over 8 years ago
2795a rev 10981 fixes the temp-table buffer delete (see testcases/uast/procedures/shared_tt_run.p
). There is a conversion change, so reconversion is required for any further testing. The main rule is: if a temp-table gets deleted, all its associated buffers must be deleted, too.
There is another issue related to the buffer order reported by the SESSION:FIRST-BUFFER
list - currently, P2J adds buffers to this list in their "creation order". But I don't think this is correct: for the temp-tables, the order looks like is given by the temp-table creation order and only after that, by the buffer creation order. I don't plan to fix this in the scope of this task.
Next I'm checking how buffers for permanent tables are deleted.
#47 Updated by Constantin Asofiei over 8 years ago
2795a rev 10981 looks like is working OK with the permanent buffers, too - see testcases/uast/procedures/shared_pt_run.p
. But there is the same problem - the buffer order in the SESSION:FIRST-BUFFER
list is incorrect. Again, P2J reports them following the creation order, while 4GL uses some other order... not sure why, as all the buffers are for the same table.
I'm starting MAJIC testing with rev 10981 next.
Eric: please run the testing again (don't forget to reconvert). Note that I haven't fixed explicitly the performance issue yet... the only conversion/runtime change which might affect it is that I'm setting the TemporaryBuffer.global
flag for NEW SHARED GLOBAL
temp-tables, but I couldn't duplicate. I couldn't find a reason why this is happening.
#48 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
Eric: please run the testing again (don't forget to reconvert). Note that I haven't fixed explicitly the performance issue yet... the only conversion/runtime change which might affect it is that I'm setting the
TemporaryBuffer.global
flag forNEW SHARED GLOBAL
temp-tables, but I couldn't duplicate. I couldn't find a reason why this is happening.
The changes between rev 10979 and 10981 looked OK to me, and I've run this through the full search test again.
The good news is that the performance issue seems to be resolved; I'm guessing this was due the expense of processing the inappropriate handle error.
The bad news is that we had regressions: 29 tests failed, when normally only 6 should. I have not analyzed the results; however, they are posted at #1868-79. The 2 timeout errors are not related to this issue.
#49 Updated by Eric Faulhaber over 8 years ago
Eric Faulhaber wrote:
The bad news is that we had regressions: 29 tests failed, when normally only 6 should.
I am not sure I was working with a clean database for this run, so I am restoring the database and re-running this test set.
#50 Updated by Eric Faulhaber over 8 years ago
The full search test re-run showed no regressions (only the expected 6 failed tests), so it seems my previous run was due to using an altered database instance.
The running time of both of the last two runs was at the high end of what I normally see for this test set, so there might a slight performance degradation, but nothing drastic.
I'll run the remaining unit test sets and report any regressions.
#51 Updated by Eric Faulhaber over 8 years ago
The common search and the system maintenance CRUD test sets both completed with no new regressions. The developer test set hung (an intermittent problem not related to this issue), so I am running it again.
#52 Updated by Eric Faulhaber over 8 years ago
There seems to be one test failing that wasn't before, in the developer test set:
com.something.calendarMaintenance.RenjhgjhgjgjgMaintenanceTest.cSearchCalendarYearCurrent
I've posted the full results to #1868-80.
I also tried running this test in single mode. The result was the same: #1868-81.
I'm going to try running this with the current P2J trunk version to see if I can eliminate task branch 2795a as the cause of the regression.
LE: GES modified the package and class name above to remove customer-specific references.
#53 Updated by Eric Faulhaber over 8 years ago
Eric Faulhaber wrote:
I'm going to try running this with the current P2J trunk version to see if I can eliminate task branch 2795a as the cause of the regression.
Confirmed that we have the same error in the trunk (rev. 10961), so 2795a/10981 is not the cause. If this branch has passed regular regression testing, please merge to trunk.
#54 Updated by Constantin Asofiei over 8 years ago
2795a rev 10982 adds support for FRAME:BORDER-
attributes - this was required as the fixes in this branch exposed show-stopper issues in the GUI tests.
#55 Updated by Constantin Asofiei over 8 years ago
Greg, if 2795a rev 10981/10982 look OK to you, 2795a can be released.
#56 Updated by Greg Shah over 8 years ago
Code Review Task Branch 2795a Revision 10982
The changes look good.
#57 Updated by Greg Shah over 8 years ago
Some questions:
1. The issue noted about NEW GLOBAL SHARED temp tables not reusing existing buffers seems fixed in SVM.addTempTable()
, correct?
2. You mentioned an issue with the TemporaryBuffer.global
flag. Is this still an issue?
3. If we merge this to trunk, I guess that the 454 testcases will have the following regressions until 2875a is merged:
- screen flickering on every click
- a visible scroll-bar issue
Am I understanding correctly?
#58 Updated by Constantin Asofiei over 8 years ago
Greg Shah wrote:
Some questions:
1. The issue noted about NEW GLOBAL SHARED temp tables not reusing existing buffers seems fixed in
SVM.addTempTable()
, correct?
Correct. If temp-table is already defined (global or not), a subsequent NEW GLOBAL SHARED will create a new slave buffer for that temp-table; the master buffer is created only on the very first definition of the temp-table, and not re-used.
2. You mentioned an issue with the
TemporaryBuffer.global
flag. Is this still an issue?
No, is no longer an issue: GLOBAL SHARED temp-tables survive until end of context (and this flag is used for dynamic temp-tables, too), plus the javadoc in TemporaryBuffer.makeBuffer
states that global - true if the buffer survives until end of context life; false if it expires upon leaving the top level procedure scope.
.
3. If we merge this to trunk, I guess that the 454 testcases will have the following regressions until 2875a is merged:
- screen flickering on every click
- a visible scroll-bar issue
Am I understanding correctly?
With trunk + 2795a we will not be able to get past the User Defined Alerts
window, as the window will freeze after the alert box is dismissed (as documented in #2272-406). After 2875a is merged, the two issues you mention will appear, and also the alert-box related to dialog-frame width remains (related to User Defined Alerts
window), but will no longer freeze the window. So the missing UI issue (from your list) is the unexpected alert-box related to dialog-frame width.
#59 Updated by Constantin Asofiei over 8 years ago
rebased branch 2795a from trunk rev 10962. new rev 10983.
#60 Updated by Greg Shah over 8 years ago
At this point, I think all the issues this exposed in the customer application are resolved in the trunk (when 2875a was merged).
Can you please:
1. rebase to the latest trunk revision
2. confirm that the code no longer exposes regressions in the customer app
3. merge these changes into 2647a where they will be included in a full regression testing cycle
#61 Updated by Constantin Asofiei over 8 years ago
1. rebase to the latest trunk revision
Rebased branch 2795a from trunk rev 10964. New rev 10985
A reminder that #2945 contains MAJIC source code changes and baseline changes required by this task. So, for runtime testing, the updates attached at #2945 need to be used.
#62 Updated by Constantin Asofiei over 8 years ago
Hynek, previously I had this code in FrameGuiImpl:
if (cfg.dialog) { FrameWindowGuiImpl dialogWindow = WindowManager.findWindow(wcfg.windowID); titleHeight = dialogWindow.getTitleBar().height(); }
After rebase, there is no more FrameWindowGuiImpl
class - please tell me which class replaces this. I need to find the dialog's title-bar height.
#63 Updated by Hynek Cihlar over 8 years ago
Constantin Asofiei wrote:
Hynek, previously I had this code in FrameGuiImpl:
[...]After rebase, there is no more
FrameWindowGuiImpl
class - please tell me which class replaces this. I need to find the dialog's title-bar height.
The new class name is DialogBoxWindow
.
#64 Updated by Constantin Asofiei over 8 years ago
Hynek Cihlar wrote:
The new class name is
DialogBoxWindow
.
Thanks, this solves the compilation problem (committed to rev 10986) but unfortunately with trunk + 2795a the GUI project fails after test selection.
The problem I'm seeing is this, after selecting the test: for a dialog frame, this code in FrameGuiImpl.initialize
:
if (wcfg.dialog && wcfg.windowID == -1) { // if no dialog window has been created, create it here DialogBoxWindow dialogWindow = new DialogBoxWindow(wcfg.title); // realize early, the window may be needed even before // it is shown for the first time dialogWindow.realize(); // assign the window id so it is attached in super.initialize() wcfg.windowID = dialogWindow.getId().asInt(); } super.initialize(id, wcfg);
sets the wcfg.windowID
correctly, but after super.initialize(id,wcfg)
is called, the wcfg.windowID
gets set to 1
(the ID of the default window). Later in initialize
, when this line is executed:
DialogBoxWindow dialogWindow = WindowManager.findWindow(wcfg.windowID);
I get a
ClassCastException
as the wcfg.windowID
is set to 1...
Can you please take a look? I've placed the GUI jars and sources (so that you don't need to reconvert with 2795a) into devsrv01:/tmp/2795a
.
#65 Updated by Hynek Cihlar over 8 years ago
Constantin Asofiei wrote:
Hynek Cihlar wrote:
The new class name is
DialogBoxWindow
.Thanks, this solves the compilation problem (committed to rev 10986) but unfortunately with trunk + 2795a the GUI project fails after test selection.
The problem I'm seeing is this, after selecting the test: for a dialog frame, this code in
FrameGuiImpl.initialize
:
[...]sets the
wcfg.windowID
correctly, but aftersuper.initialize(id,wcfg)
is called, thewcfg.windowID
gets set to1
(the ID of the default window). Later ininitialize
, when this line is executed:
[...]
I get aClassCastException
as thewcfg.windowID
is set to 1...
FrameConfig.windowID
in case of a dialog box is used for (a) specifying the id of the dialog window the frame will be attached to during initialize (in Frame.attachToWindow()
) and (b) after the frame has been attached to indicate the "logical" parent (so that FRAME:WINDOW
attribute returns the correct value , default window handle is expected in this case). I agree this is a bit schizophrenic and certainly a subject for improvement.
I think the solution is to use Frame.topLevelWindow()
to get the actual window owner instead of WindowManager.findWindow(cfg.windowId)
since cfg.windowId after Frame.initialize()
holds the logical window.
#66 Updated by Constantin Asofiei over 8 years ago
Hynek Cihlar wrote:
I think the solution is to use
Frame.topLevelWindow()
to get the actual window owner instead ofWindowManager.findWindow(cfg.windowId)
since cfg.windowId afterFrame.initialize()
holds the logical window.
OK, this fixes the issue and now the client gets to the User Defined Alerts
window and from this to the main test window.
User Defined Alerts
window:
- a visible scroll-bar issue (this is a regression, introduced by trunk rev 10963 I think - the window mngmt improvements)
- unexpected alert-box related to dialog-frame width
#67 Updated by Greg Shah over 8 years ago
Hynek: It was my understanding that both of those issues were already resolved in 2875a.
#68 Updated by Hynek Cihlar over 8 years ago
Greg Shah wrote:
Hynek: It was my understanding that both of those issues were already resolved in 2875a.
Ad the visible scroll-bar: I was able to reproduce it and the fix in 2875a worked ok. I will check in 2795a.
Ad the unexpected alert-box. Sorry I must have overlooked this one, there is no such fix for this in 2875a. I will fix this as soon as I finish the above.
#69 Updated by Hynek Cihlar over 8 years ago
Hynek Cihlar wrote:
Greg Shah wrote:
Hynek: It was my understanding that both of those issues were already resolved in 2875a.
Ad the visible scroll-bar: I was able to reproduce it and the fix in 2875a worked ok. I will check in 2795a.
This seems to be a frame layout issue. The scroll container shows the scroll bars because there is a visible skip frame item spanning larger than the visible size. The question is why is the skip there or why is it visible. This is still a WIP.
Ad the unexpected alert-box. Sorry I must have overlooked this one, there is no such fix for this in 2875a. I will fix this as soon as I finish the above.
Frames in dialog-box have zero border, even with NO-BOX is not specified. This particular case was caused by Frame.canSetWidthChars()
which validates the new size against a minimum size. The minimum size is increased to account for the border. So we ended up with incorrect minimum size and hence the alert-box. I have fixed this particular case, but there is more code like this that needs to be fixed. And btw the minimum size was also being calculated wrong for regular GUI frames, it just never appeared.
#70 Updated by Hynek Cihlar over 8 years ago
Hynek Cihlar wrote:
Hynek Cihlar wrote:
Greg Shah wrote:
Hynek: It was my understanding that both of those issues were already resolved in 2875a.
Ad the visible scroll-bar: I was able to reproduce it and the fix in 2875a worked ok. I will check in 2795a.
This seems to be a frame layout issue. The scroll container shows the scroll bars because there is a visible skip frame item spanning larger than the visible size. The question is why is the skip there or why is it visible. This is still a WIP.
Ok, this is not a layout issue but the missing runtime support for SCROLLABLE
attribute. The frame contains some additional items outside of the visible area but is assigned SCROLLABLE
to FALSE
and hence no bars are shown.
This issue should be resolved once 2795a is merged with 2038b which adds the support for SCROLLABLE
attribute.
#71 Updated by Greg Shah over 8 years ago
I have fixed this particular case, but there is more code like this that needs to be fixed.
You have fixed this in 2038b?
How much more code needs to be fixed? Do you propose to fix these places now?
#72 Updated by Hynek Cihlar over 8 years ago
Greg Shah wrote:
I have fixed this particular case, but there is more code like this that needs to be fixed.
You have fixed this in 2038b?
Yes I have fixed this particular case in 2038b.
How much more code needs to be fixed? Do you propose to fix these places now?
I checked all the places where wrong box/border size is assumed for dialog-box. Some are obvious and I will fix these. Some are used in ChUI and possibly by GUI as well. The ChUI cases are risky and would require more testing, a wild guess plus 2 MD to implement and regression test.
#73 Updated by Hynek Cihlar over 8 years ago
Note that the unexpected scroll bars issue in User Defined Alerts
window is solved by #2038, task branch 2038b.
#74 Updated by Greg Shah over 8 years ago
Constantin: Please rebase from the latest trunk and put this through regression testing.
If it passes testing, please merge the changes in 2795a into 2647a. Eric will do the final testing of that branch and in that branch is how it will merge to trunk.
#75 Updated by Constantin Asofiei over 8 years ago
Greg Shah wrote:
Constantin: Please rebase from the latest trunk and put this through regression testing.
Rebased from trunk rev 10965. new rev 10988.
Full testing started.
#76 Updated by Constantin Asofiei over 8 years ago
Rebased 2795a from trunk rev 10965 10966. new rev 10989
testing again to clean some false negatives.
#77 Updated by Constantin Asofiei over 8 years ago
The only issue is with tc_item_master_007 - two records are ordered differently in the screen on step 80. Running in single mode doesn't help (as a certain DB state is required).
Anyway, I don't think this is related to 2795a changes.
Eric: please let me know if I can merge into 2647a.
#78 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
Eric: please let me know if I can merge into 2647a.
Yes, please do.
#79 Updated by Constantin Asofiei over 8 years ago
Eric, I have this conflict in recid.java
:
@Override public BaseDataType instantiateDefault() { <<<<<<< TREE return new recid(0); ======= return new recid(); } .... >>>>>>> MERGE-SOURCE }
Are you sure
instantiateDefault()
needs to initialize the var with 0 instead of unknown? I ask this because converting a recid var initializes it to unknown (new recid()
), and also in 4GL an uninitialized recid var is reported as unknown.#80 Updated by Constantin Asofiei over 8 years ago
Eric, I've merged 2795a into 2647a - see revision 10983.
With this revision, the following is needed:- for MAJIC testing - baseline and MAJIC updates from #2945
- all projects require re-conversion
#81 Updated by Eric Faulhaber over 8 years ago
Constantin Asofiei wrote:
Are you sure
instantiateDefault()
needs to initialize the var with 0 instead of unknown? I ask this because converting a recid var initializes it to unknown (new recid()
), and also in 4GL an uninitialized recid var is reported as unknown.
Sorry I wasn't able to answer in time. I was trying to find the code which led me to believe this, but I can't at the moment. I was going to suggest that you go ahead with your version. If I conclude it should be 0 after all, I'll change it back and I'll post the reason here.
#82 Updated by Greg Shah about 8 years ago
Merged to trunk as part of revision 10967.
We can close this task, right?
#83 Updated by Constantin Asofiei about 8 years ago
Greg Shah wrote:
We can close this task, right?
Correct
#84 Updated by Greg Shah about 8 years ago
- Status changed from WIP to Closed
Please archive the task branch.
#85 Updated by Greg Shah over 7 years ago
- Target version changed from Milestone 12 to GUI Support for a Complex ADM2 App