[pypy-dev] Continuations and sandboxing

William ML Leslie william.leslie.ttg at gmail.com
Mon Jan 10 09:22:27 CET 2011


On 10 January 2011 15:24, Nathanael D. Jones <nathanael.jones at gmail.com> wrote:
> Hi folks,

Hi!

> 2) Serializeable continuations. With gameplay being based on good plot and
> story flow, continuations are critical to allow straightforward
> implementation of 'workflows' that depend on user choice at every turn.
> 3) Tail-call elimination.  By nature, players will accumulate a very large
> call stack. While this isn't terribly bad a first glance, the following
> issue combines with it to cause a very big problem:
> When code changes underneath a continuation, we need to determine how to
> resume flow. One option is annotating a checkpoint method in each code
> 'file'. However, if a user's call stack includes every file in the system,
> each change will cause them to restart.
> Tail-call elimination would help eliminate unneeded stack frames and
> minimize re-spawning.

I wonder if you don't want instead to manage the (user) dynamic
context yourself - if players already need to remember to write all
actions in a tail-recursive manner, it is probably worth making that
API explicit, and if you do that, the underlying implementation
doesn't need to do TCE at all.  But I guess the existing stackless
support should be good enough if you just want one-shot continuations.

> 4) Dynamic code loading. Users will be able to 'branch' their own version of
> the world and share it with others. There may be thousands of versions of a
> class, and they need to be able to execute in separate sandboxes at the same
> time. Source code will be pulled from a Git repository or some kind of
> versioning database.

Quite like this idea.

You do have to deal with a bunch of (fairly well known) problems,
which any specific implementation of dynamic code loading is going to
need to solve (or not).  Pypy doesn't currently implement any
hot-schema-change magic, and reloading has always been error prone in
the presence of state.  First-class mutable types make it particularly
difficult (there is no sensible answer to what it means to reload a
python class).

The one issue that interests me is where you implement the persistence
boundary - do you go with orthogonal persistence and act as if
everything is preserved, or assume all user code is run within some
sort of (fast and loose) transaction that can be re-entered at will,
providing an API for persistent data access?  The second case makes
the reloading question a bit more reasonable, because you can always
throw away the current delta and replay the external effects, assuming
the interface for the external events hasn't changed significantly.

-- 
William Leslie



More information about the Pypy-dev mailing list