|
|||||||
In a previous posting, we talked about passing by reference versus passing by value. In that article, we mentioned we'd explain how this could adversely impact your programs.
At a client site, we installed a custom index update program. This function allows the customer to run multiple indexers at a time, with each indexer updating only a subset of the indexes on each machine. Additionally, the UI displays statistics about the indexes, the time it takes to perform each update and other useful information. (If you're interested in said product, then please, by all means, let us know.) We recently discovered that some indexes were never updating, and a check showed that the test lock we placed on the index was never being released. A quick check of the code showed that this was theoretically impossible, and a detailed check validated that assumption. However, the theory was quite wrong since the lock was never being released. A test run through a number of indexes, checking variables after every line of code, examining the results of status(), get_status(), @FILE.ERROR and even get_EventStatus showed no errors and nothing we did not expect to occur. Finally, after close to a dozen passes, we had results. The code is basically call set_status( FALSE$ )
if locked then call index.flush( fileName, indexField ) if get_status( errorText ) then gosub processError end end else * // ZZIDX010: Table Name %1%, IndexName %2% is currently locked. | * // Index update skipped logText = zzx_res2str( ZZ_INDEXER_RESKEY$, "ZZIDX010", | fileName : @FM : indexField, | TRUE$ ) gosub updateLog end if locked then unlock hFileName, indexField : "*" : ZZ_INDEX_TOKEN$ else tableId = fileName rowId = indexField gosub setFsError gosub processError end end One one particular index FOO, indexField was changed to BAR. As the code continued, it attempted to unlock the BAR index token, leaving the FOO index token locked. At last, we had an answer to why some locks were not being released. It did, however, open a whole new set of questions. One was why why was the variable being changed. The other was what is the relationship between FOO and BAR. After carefully examining the index definition records, it was clear that FOO was not only a BTREE index, but was also the source of a relational index on a secondary table with BAR being the target field. Apparantly, somewhere in the index.flush code, the system is swapping out indexField from the source field to the target field, a clear case of your source variables being affected by passing by reference. We changed the index.flush call to
call index.flush( fileName, (indexField : "") )
and the lock was released as expected. Labels: Basic+, behaviour, Bugs, Compiler, indexing, variables |
|||||||
| |||||||
2 Comments:
Simple and clever way to pass a variable as an argument without having it mangled on the return visit! Nice job.
By Don Bakke, At 19 August 2013 at 20:05
Thanks Don. We seem to have hit a spate of such things lately so it's good to have an easy way of addressing it!
By Sprezz, At 19 August 2013 at 20:41
Post a Comment
Subscribe to Post Comments [Atom]
<< Home