Monday, February 26, 2007

writing Smallworld symbols/styles to JPG images

Recently a question appeared on sw-gis asking how to output your Smallworld styles to some external format.

If you download the SourceForge MagikComponents (http://sourceforge.net/projects/magikcmpnts) [MagikComponents has been moved to https://www.assembla.com/code/magik-components/subversion/nodes/mclib/trunk 
] you should see a number of modules that provide results similar to what you are asking or provide examples of how you might render styles to JPG files.
  • modules\mclib_style_images provides code to create jpg files from the various style records.
  • modules\mclib_case_html_reporter provides code that creates an HTML output for your CASE tool. Part of this code (see case_html_report_plugin.output_style_info_for() ) creates jpeg files of the various geometry field styles.

Friday, February 23, 2007

ds_transfer might be corrupting your backups

If you are using the ds_transfer function in "hot" mode to create backups from your production VMDS, you run the risk of corrupting your backup files so that they cannot be properly restored. I had originally published a post about this to the sw-gis group in July of last year. Recently I was at a client site where the backup scheme used ds_transfer in "hot" mode and I realized that it would be helpful to repost this information in this blog.

If you are using PowerOn, it is possible that the original implementors set up your backup scheme to use ds_transfer in "hot" mode. You may want to read the following article and see if your backups are in jeopardy.

Original Article follows....

Since there is a discussion about backups and the ds_transfer mechanism was mentioned as a solution I thought I would throw out a warning about that approach. Simply put, when using ds_transfer.new() in "hot" mode, you should ensure that no one is writing to the database while you are performing the ds_transfer.
The typical ds_transfer scenario involves ds_transferring one DS file at a time. Imagine that you ds_transfer gdb.ds and it takes a total of 15 minutes. 10 minutes into the ds_transfer a user writes a fiber(1234) RWO and geometry to that partition. But the alternative that was being written to had already been processed at minute 2 of the 15 minute process. After the 15 minutes are done, the ds_transfer starts working on the rwo.ds file.
You will not see a problem in the live production dataset, but you will now have a situation where the "ds_transferred" dataset has an inconsistency between the rwo.ds and the gdb.ds. This is a simple scenario, but imagine that changes are at a larger scale or possibly involve adding/removing alternatives while a hot ds_transfer is in progress. These will all be permitted actions but may cause unintended results in the "ds_transferred" files. If you are using the ds_transfer.new() with "hot" mode you should try opening a copy of your recently ds-transferred files to see if they are consistent with each other.
If you want to continue using the ds_transfer functionality to perform "hot" backups, refer to ds_transfer.transfer_partition() to see how it might be beneficial to you. This method has the advantage of allowing you to snapshot all DS files in a partition at the same time so you will not encounter any of these data consistency issues.


Wednesday, February 14, 2007

controlling runaway procedures at the Magik prompt

Have you ever run a procedure at the Magik prompt and it kept running and the only way you could terminate it was to close the Magik session? There is another way!

I was working on a procedure today that parses the results of a Relational Integrity Check and summarizes the errors by rwo_type. I wasn't sure how long it would take to run, so I forked the procedure in a new thread.

For illustration here, I have created a procedure that runs an endless loop. If you ran this at the Magik prompt, you would need to terminate the session in order to end the loop. To avoid this hassle, I have forked the procedure in a new thread using fork_at(). You can review the public comments for this method in the class browser to learn about the valid arguments.

MagikSF> th << _proc()
_loop

_endloop
_endproc.fork_at(5)
$

Now it is easy to query the thread to see if it is running or not...

MagikSF> th.status_description
$
"runnable"

You can pause the thread...

MagikSF> th.suspend()
$
thread(unnamed suspended 5)
MagikSF> th.status_description
$
"suspended"

You can resume a paused thread...

MagikSF> th.resume()
$
thread(unnamed runnable 5)
MagikSF> th.status_description
$
"runnable"

Or you can finally terminate the thread...

MagikSF> th.kill()
$
thread(unnamed runnable 5)
MagikSF> th.status_description
$
"terminated"