links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Last updated at 12:51 am UTC on 17 January 2006
SPrevayler is a prevalence layer for Squeak. System prevalence is based on the idea that all data is kept in RAM. So the system runs very fast without any lack of data security.
It can render your data out as XML or as binary Squeak Format, which is very fast. You can simply make your classes persistent by using a simple transparent proxy or you can use the full power of this solution and write your own commands.
In order to use this project you need to have SIXX in your image!


There are two ways to install it.

Contact me via mail: mailto:slomo.minnowwiki.5.marco_paga@dfgh.net



Transparent prevalence

Quote of mail:
Marco Paga mail at marco-paga.de
Fri Feb 28 13:48:04 CET 2003
I wrote a little Proxy that does the things you wanted. Here an example:

 | p c base proxy|
   base_ FileDirectory on: (FileDirectory default pathName,
                            FileDirectory slash , 'testBase').
 p := Prevayler withSystem: (MPTestSystem value: 0) on: base.
 proxy_ PrevalenceProxy prevayler: p.
 proxy addValue: 17.

every message that goes to the proxy is handeld by the prevalence layer. You have to pay attention in the case of creating a new prevayler because then you have to create a new proxy too.

Here you can find a UML sequence diagram:
External Image

The Formats

You can easily change how Sprevayler writes Objects to disk by changing Prevayler>>getDiskIOClass. To use XML you need to have SIXX installed!
Currently two possibilities:


But that idea alone doesn't keep your data. The system gets fotographed from time to time and the snapshot gets written to disk. So we can rebuild the state of some particular points in timeline.
But now we want to run transactions on it. How to do that without taking snapshots of the whole huge system every time?
We write the commands to disk, too. The commands that are issued to the system get written to disk and the executed on the hot system.
To rebuild the state we look for the newest snapshot and go through the command logfiles that follow the snapshot and execute one command after another.

That's all.

Time related

But what about commands that need the current time and date? These can work,too. There is one limitation: Your commands need to always give the same results based on a time (determenistic commands).
Before the commands are stored to disk they are put in an ClockRecoveryCommand that restores the time before the real command is executed in the case of restorage (Design Pattern: Decorator).


 Object subclass: #MPTestSystem
  	instanceVariableNames: 'value '
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'Prevayler-Tests'

We just want to provide a method to add a number to the value of the system.

addValue: anObject
value_ value + anObject.
Transcript show: 'Added value: ',value asString, 'Time: ',clock time asString ; cr.

setValue: anObject

   PrevaylerCommand subclass: #MPTestCommand
	instanceVariableNames: 'value '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Prevayler-Tests'

As a class method you need to add one that adds parameters to it.
value: anObject
^super new setValue: anObject "Add the setValue: Method!"

On the instance side we need to add the executeOn method to override the super class method.
executeOn: aSystem atTime: anAlarmClock
aSystem addValue: value.

This should be the one command that is enough for our exmple. Just adding a nmber, not more. If you want to access the "current" time you have to use the provided AlarmClock not any other timesource.

  | p c base |
  base_ FileDirectory on: (FileDirectory default pathName , 
                           FileDirectory slash , 'testBase').
  p := Prevayler withSystem: (MPTestSystem value: 0) on: base.
  c_ MPTestCommand value:5.
  p executeCommand: c.


Here you can have a look at a UML class dia of the system. I just created it that you can have a short overview.
External Image


Next features to implement:

Version Comments:


Author: Marco Paga (Contact: mailto:slomo.minnowwiki.5.marco_paga@dfgh.net)
Developers : David Salamon and Adrian Lienhard
License: The license I use for SPrevayler is the MIT license.

Your comments:
what is the MIT license? What if you have no license?
where is a website running this?
maszproduction@yahoo.com gavin schuette

You can find the mit license here: http://www.opensource.org/licenses/mit-license.php . It is a very free license, so I thought it would be a good choice. I wanted to choose a license but a very free one because I don't like source that is not covered with any license, becuase then you don't really know if you can use it and of course I want to protect myself.
Right at the moment there is no webiste running it. SPrevayler is just for transparent persistence in squeak. To make a app persistent you can just use your source and add the proxy to it as the model and it will work.

Hi. Thanx u, kbye.
I've been trying to use this in my Seaside application and ran into some problems concerning the continuations. Weird to trace down though –

Hi if you can send me an email with more detailed information I could have an eye on it.
You can find my address on this page or on my personal page.
According to this page, we should have a SixxAdapter. In the mcz attached, we don’t.
I don’t think anyone has tried running the code in the mcz against sixx.

When you try to bring up the Prevayler against an xml-based directory of snapshots and clogs, you get a problem with DiskIOClass returning a SixxWriteStream which doesn’t understand “readOnlyFileNamed”.

oldFileNamed: aFilename
^ self new setStream: (self DiskIOClass readOnlyFileNamed: aFilename).

All I’ve done to get this is swich around the commenting in PIOAdapter>>DiskIOClass, so that it returns SixxWriteStream, and not the default ReferenceStream.

Thank you for your comment. I will have a look on it asap and release a new monticello version.
I tested it on a clean 3.7 under Linux with Sixx and ReferenceStreams and the test cases worked well.