You are currently browsing the category archive for the ‘porting’ category.
If you are developing in Squeak/Pharo and deploying in GemStone, then you should check out Ken’s work.
Ken Treis has started work on a MockGemStone package that provides implementations for a couple of the Rc classes discussed in GemStone 101:Transaction Conflicts. The package can be loaded into a Squeak image and the classes can be used to develop a Seaside application in Squeak that will run in both GemStone and Squeak environments.
If, after reading some of the documentation, you find that you have more questions about GemStone, feel free to write comments to this post or you can join the GemStone Mailing list. A number of long-time GemStone users monitor the list (in addition to the GemStone engineering staff) and I’m sure they will be glad to answer your questions.
This week I’ve been ‘heads down’, getting GemSource (the port of SqueakSource to GemStone) ready to go live, so I haven’t had a lot of time to write.
When GemSource goes live next week, it will be a read only site (at first), but we will have published all of the packages (Monticello, Hyper, FastCGI, Seaside, and SqueakSource) for your enjoyment.
If you are using threads (forking Smalltalk processes) in your Seaside application, then you will need to make some relatively minor mods to your code.
In addition to managing concurrent access to objects (via critical blocks), all threads must be coordinated in relation to transaction boundaries. You cannot afford to have multiple threads aborting and committing without some sort of coordination – the method SeasidePlatformSupport class>>doTransaction: provides that coordination.
SeasidePlatformSupport class>>doTransaction: acquires the transactionMutex, performs a beginTransaction, evalutes the block passed in as an argument, performs a commitTransaction and returns the result of the commitTransaction (a Boolean). The transactionMutex ensures that your transaction will not interfere with any other ongoing transaction, including servicing an HTTP request.
In the SqueakSource Seaside application, there is a CacheThread that runs once a day and the code looks like this:
startCacheThread self isCacheThreadRunning ifTrue: [ self stopCacheTread ]. cacheThread := [ self updateCache. self updateStatistics. (Delay forDuration: 1 day) wait. ] forkAt: Processor userBackgroundPriority
After adding a call to SeasidePlatformSupport class>>doTransaction:, the code looks like this:
startCacheThread self isCacheThreadRunning ifTrue: [ self stopCacheTread ]. cacheThread := [ SeasidePlatformSupport doTransaction: [ self updateCache. self updateStatistics. ]. (Delay forDuration: 1 day) wait. ] forkAt: Processor userBackgroundPriority
If you choose to run the thread in the same VM as the Seaside application, you need to pay attention to how much time you spend inside of a doTransaction: block, because HTTP requests won’t be serviced while the block is executing.
If you’ve got long running transactions, then you should unconditionally move the thread into a separate GemStone VM. In the separate VM, the transaction duration will not affect the response times for HTTP requests.
Here’s an sample topaz script for running this thread in a separate VM (I’ll cover topaz in more detail in another post):
! ! Sample script for updating ! SSRepository cache and statistics ! set user DataCurator pass swordfish login run ! ! enter manual transaction mode and ! install SigAbort handler ! System transactionMode: #manualBegin. Exception installStaticException: [:ex :cat :num :args | System abortTransaction. System enableSignaledAbortError ] category: GemStoneError number: 6009 subtype: nil. System enableSignaledAbortError. ! ! Start update loop ! [true] whileTrue:[ SeasidePlatformSupport doTransaction: [ SSRepository updateCache. SSRepository updateStatistics. ]. (Delay forDuration: 1 day) wait. ]. %
If you have more than one thread in your Seaside application, you can fork off additional processes in the script.
My recomendation is that you plan on moving all of your background threads to a separate VM. In the long run it will be simpler to manage your threads and you won’t have to worry nearly as much about how long it takes individual operations to complete.
One of the very nice features of GemStone is that you don’t have to do anything special to take advantage of persistence. With other smalltalk dialects (Squeak, VW, VA, and Dolphin) objects that are referenced by the global Smalltalk will be ‘kept alive’ in the image. With GemStone, any objects referenced by a persistent root (I’ll explain why I didn’t say ‘Smalltalk’ here in a later post) will be ‘kept alive’ and ‘automatically’ saved in the data base.
In a generic GemStone application you do have to explicily manage transaction boundaries using the following methods:
- System class>>beginTransaction
- System class>>commitTransaction
- System class>>abortTransaction.
For the GemStone port of Seaside, we have embedded the transaction boundaries in the Seaside framework, so you don’t have to change your application at all – a beginTransaction is performed when the request comes in from the http server and a commitTransaction is performed right before the response is shipped back out to the http server.
This means that while your Seaside application is responding to the request, you have an up-to-date ‘view’ of the object graph and any changes that you make to persistent objects will be committed to the data base, without any special coding on your part.
As you scale your application you will eventually be adding more Seaside vm’s to serve your pages and when you do, you will then need to worry about transaction conflicts. I’ll cover transaction conflict avoidance in a later post.