I don't think such support exists in current languages. I think what I want to do could be solved by a "workflow engine". But the problem I have with workflow's is generally they are:
I've investigated serializing iterators in C# but that doesn't get me exactly where I want to be. I'm current looking at putting together a DSL in Boo but not sure if I'll be able to get coroutine-like behaviour into Boo, and be able to serialize it as well.
Here is limited fictional example of what I'd like to do. The main issue is that at any point in a routine you may need to get user input. The time between inputs could be very long so the state of service will need to be serialized to disk.
def RunMachine(user)
var lever = user.ChooseLever()
lever.Pull()
var device = CreateDevice(user)
machine.Add(device)
machine.Run()
def CreateDevice(user)
var color = user.ChooseColor()
var shape = user.ChooseShape()
return Device(color, shape)
I have a working "engine" in CPython. It piggy-backs on the iterator/yield support in python. So code looks like this:
def escape(self, you):
roll = yield self.game.rollDice(you)
if roll < 5:
self.caughtAction(you)
Where rollDice
can be interrupted. with some user action. CPython however doesn't serialize iterators.
Since the whole state of the game can be defined as a sequence of commands, I serialize the game state up to the point at where a coroutine started then the remaining list of commands. So to save/restore looks like this:
def dumpGameState(game):
if gameState.partialState:
return pickle.dumps({ 'partialState': game.partialState, 'partialInputs': game.partialInputs })
return pickle.dumps(game)
def loadGameState(data):
state = pickle.loads(data)
if state.__class__ is Game:
return state
r = pickle.loads(state['partialState'])
for input in state['partialInputs']:
game.execute(**input)
return game
I still find this unsatisfactory. As I end up having to use 'yield' on almost every method. I'd rather not have to specifically decorate a method. Also it quite fails at serialization.
Currently I'm investigating going a functional route, as functional languages seem to have better support for metaprogramming/DSL creation. Currently looking at
I'm hopeful that with strong enough metaprogramming facilities I can automate the state storage mechanism. Also, if I go the F# route, I'm pretty sure I can fall back on the "technique"/(hack) I used to serialize iterators.
Funny that you should ask this today, and then later I read about Continuations in Mono. Looks like the kind of thing you're after. In particular there's a reference to Microthreading in Second Life, including this description:
SecondLife required that code be suspended at any point in time and that its entire state be serializable into a format suitable for storage into a database. Serialized state could then be restored at a different point in time or on a different computer (for example while moving from node to node).
Unless I've misunderstood you, this could be a good avenue to explore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With