I made a breakthrough yesterday, I feel like telling someone about it, even though it is really entirely “inside baseball.” So the three of you on this beta forum have the dubious honor of being on the receiving end of this missive.
When opening a shared database on the client, Panorama performs these steps:
- load the file from disk into ram
- contact the server
- if necessary, load updated new generation from server
- if necessary, synchronize data from server
Of course, it’s important that these steps happen in the correct order. And they do.
However, there is a somewhat common situation I neglected to think about when developing this. What if the shared database is opened via a procedure, like this?
opendatabase "my shared database"
// more stuff happens
// after database is open
The problem is, up until now Panorama X has performed this in the wrong order, like this:
- load the file from disk into ram
- contact the server
- MORE STUFF (what is this doing here??)
- if necessary, load updated new generation from server
- if necessary, synchronize data from server
That is obviously very wrong! What needs to happen is for Panorama to set MORE STUFF aside, and wait until all the server activity is done, then MORE STUFF needs to resume. I already had other areas where code was temporarily set aside and then resumed later, so I was pretty sure it would be possible. Problem was, when I wrote code to do this, it didn’t work. I was setting MORE STUFF aside, but somewhere in the very complicated code to get the server connection established, MORE STUFF was getting corrupted, so that it didn’t run at all at the end.
This proved to be very difficult to untangle. In fact, I was pretty much stuck for six days. There was nearly ten thousand lines of code that were possible suspects. Kind of a needle in a haystack. I wound up building some special tools just to help filter out possible suspects (and if I hadn’t already created the new Debug Instrumentation feature, I would have needed to for this, couldn’t have found the problem without it).
Finally, yesterday I identified the culprit. Once I found the spot, it only took a few lines of code to fix the problem. Now it reliable does everything in order.
- load the file from disk into ram
- contact the server
- if necessary, load updated new generation from server
- if necessary, synchronize data from server
- MORE STUFF (yeah!)
What a relief! When people ask me when a release will be ready, this is the sort of issue that makes predictions nearly impossible.
If you’ve read this far, thanks. Since you may be interested, I’ll tell you about a related issue that I solved before this, with less angst. If a single user database has an .Initialize procedure, you might expect it to work like this:
- load the file from disk into ram
- run .Initialize
- MORE STUFF
And in fact, Panorama 6 and earlier do work that way. But Panorama X has note. Instead, it would run in this order:
- load the file from disk into ram
- MORE STUFF
- run .Initialize
But this isn’t really right. So now, starting with 10.2 b7, it will run in the correct order:
- load the file from disk into ram
- run .Initialize
- MORE STUFF
In addition, Panorama X is now more flexible about what kinds of code can be included in the .Initialize procedure.
I did the rearranging of the .Initialize first, because I thought it would be easier. And I was right, I was able to get that working fairly quickly. I thought the same trick would work for the server code, and ultimately it did, but with the extra wrinkle that took six days to figure out. By the way, it all works together now if you have a shared database with an .Initialize procedure, everything runs in the correct order.
- load the file from disk into ram
- contact the server
- if necessary, load updated new generation from server
- if necessary, synchronize data from server
- run .Initialize
- MORE STUFF (yeah!)
I still need to do some more testing, for example to confirm that the .Initialize procedure will work if it contains opendatabase statements that open other shared databases, and to confirm that server variables now work in .Initialize code. I think these will work, but they haven’t been tested yet. Once the testing is finished, the next step will be to finally release b7. So I’ll stop writing now and get on with the testing.