namgk / ambienttalk

Automatically exported from code.google.com/p/ambienttalk
0 stars 0 forks source link

Coroutines / awaiting futures by 'blocking' #33

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Proposal to allow an actor to block on a future, but in an event-driven way 
(i.e. blocking as in 
suspending while not blocking the main actor event loop).

I would like to be able to implement a construct:
{{{def val := await: future}}}
That can be used to block on the value of a future without disrupting control 
flow (i.e. without 
requiring the use of {{{when}}}. Unlike the typical {{{touch}}} operation on 
classical futures, the 
{{{await}}} operation does not block the actor's entire event loop. The actor 
simply continues 
processing other messages until it encounters a message that 'wakes up' the 
execution 
(coroutine) that is awaiting the future.

The reason why I want a construct like this is that it allows code to hide 
asynchrony. Asynchrony 
no longer has to leak through to the caller. This is useful for software 
evolution purposes.

This construct could be implemented if we extend AmbientTalk with coroutines: 
lightweight co-
operative threads. It does not introduce data races because of the cooperative 
scheduling: no two 
coroutines can ever be active within the same actor.

Implementing real lightweight coroutines in the interpreter is tricky because 
it requires an 
explicit reification of the runtime AmbientTalk stack, which we don't have. It 
is possible to 
implement heavyweight coroutines, however, by suspending threads:
  - coroutine yield = suspending the current thread & spawning a new thread
  - later, a coroutine can be re-activated by resuming the suspended thread

This leads to a model with one JVM thread / coroutine, which is heavyweight but 
OK as long as 
coroutines are not heavily used in AmbientTalk.

Original issue reported on code.google.com by tvcut...@gmail.com on 21 Jul 2009 at 5:08

GoogleCodeExporter commented 8 years ago
While coroutines have the good property that they can "contain" asynchrony in a 
function without "leaking" the 
asynchrony to its callers, this introduces dangerous interleaving ("plan 
interference") hazards. If a function 'f' 
previously worked synchronously, but now uses the proposed `await` construct, 
then it would cause all of its 
callers to "block" as well, without those callers being notified of this. Using 
`when`, f must return a future, thus 
changing its return type, requiring its callers to adapt to the new semantics. 
Thus, they are warned that f cannot 
complete atomically in a single turn anymore, and can take this into account.

Original comment by tvcut...@gmail.com on 20 Mar 2010 at 6:39