Skip to content

Instantly share code, notes, and snippets.

@agnaldo4j
Created October 5, 2011 13:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save agnaldo4j/1264388 to your computer and use it in GitHub Desktop.
Save agnaldo4j/1264388 to your computer and use it in GitHub Desktop.
PrevaylerJR on Scala
import java.io._
abstract class Command[IN, OUT] extends Serializable { def executeOn(system: IN): OUT }
class Prevayler[SYSTEM](private val storageFile:File) {
private var _system: SYSTEM = _
private var _journal: ObjectOutputStream = _
def restoreState(initialState: SYSTEM): SYSTEM = {
var tempFile: File = new File(storageFile.getAbsolutePath + ".tmp")
_system = restoreState(initialState, storageFile, tempFile)
_journal = new ObjectOutputStream(new FileOutputStream(tempFile))
writeToJournal(_system)
if ((!storageFile.exists || storageFile.delete) && tempFile.renameTo(storageFile)) return _system
throw new IOException("Unable to rename " + tempFile + " to " + storageFile)
}
def executeTransaction[RETORNO](transaction: Command[SYSTEM, RETORNO]): RETORNO = synchronized {
writeToJournal(transaction)
return transaction.executeOn(_system).asInstanceOf[RETORNO]
}
def executeQuery[RETORNO](query: Command[SYSTEM, RETORNO]): RETORNO = synchronized { query.executeOn(_system) }
private def restoreState(initialState: SYSTEM, storageFile: File, tempFile: File): SYSTEM = {
var state:SYSTEM = initialState
try {
val fileToRead = if (storageFile.exists) storageFile else tempFile
val input = new ObjectInputStream(new FileInputStream(fileToRead))
state = restoreImage(input)
restoreCommands(state, input)
} catch {
case endOfStreamReached: Exception => {}
}
state
}
private def restoreImage(input: ObjectInputStream): SYSTEM = input.readObject.asInstanceOf[SYSTEM]
private def restoreCommands(state: SYSTEM, input: ObjectInputStream) {
while (true) (input.readObject.asInstanceOf[Command[SYSTEM, _]]).executeOn(state)
}
private def writeToJournal(obj:Any) {
_journal.writeObject(obj)
_journal.flush()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment