Sam Ruby has written a document called "Continuations for Curmudgeons" on what continuations are, for those of us who aren't familiar with them, and how they can be used, along with some drawbacks.
Basically, continuations are preserved points of execution, such that you can resume execution of a process preserving its state. In C, they can be thought of as being implemented by setjmp() and longjmp(), among other things.
Continuations don't apply only to programming, but to design, as Use Continuations to develop complex Web applications shows, and such constructs are often referred to as some of the advantages that some scripting languages have over Java.
Continuations aren't part of Java itself: would you use them if they were? Where? What do you think about the use of continuations in general?
-
Sam Ruby on Continuations for Curmudgeons (16 messages)
- Posted by: Joseph Ottinger
- Posted on: April 14 2005 13:54 EDT
Threaded Messages (16)
- Sam Ruby on Continuations for Curmudgeons by Rodolfo de Paula on April 14 2005 17:29 EDT
- Sam Ruby on Continuations for Curmudgeons by Rodolfo de Paula on April 14 2005 17:45 EDT
- Continuations in Cocoon by Ralph G. on April 15 2005 01:37 EDT
- Continuations in RIFE by Geert Bevin on April 15 2005 03:09 EDT
- Sam Ruby on Continuations for Curmudgeons by Cameron Purdy on April 15 2005 07:43 EDT
- Sam Ruby on Continuations for Curmudgeons by Geert Bevin on April 15 2005 10:52 EDT
-
Thread base implementation by Emmanuel Pirsch on April 15 2005 12:52 EDT
-
Thread base implementation by Geert Bevin on April 15 2005 05:22 EDT
-
Thread base implementation by Emmanuel Pirsch on April 15 2005 09:17 EDT
- Thread base implementation by Geert Bevin on April 16 2005 04:14 EDT
-
Thread base implementation by Emmanuel Pirsch on April 15 2005 09:17 EDT
-
Thread base implementation by David Waddell on April 18 2005 12:16 EDT
-
Still not quite convinced by Cedric Beust on April 18 2005 02:37 EDT
- RE: Still not quite convinced by Geert Bevin on April 19 2005 12:56 EDT
- Thread base implementation by Emmanuel Pirsch on April 21 2005 09:18 EDT
-
Still not quite convinced by Cedric Beust on April 18 2005 02:37 EDT
-
Thread base implementation by Geert Bevin on April 15 2005 05:22 EDT
- Transparent migration of mobile agents by Achwamabat Machmabalamat on April 16 2005 08:29 EDT
- Sam Ruby on Continuations for Curmudgeons by Dilip Ranganathan on April 18 2005 09:18 EDT
-
Sam Ruby on Continuations for Curmudgeons[ Go to top ]
- Posted by: Rodolfo de Paula
- Posted on: April 14 2005 17:29 EDT
- in response to Joseph Ottinger
Some Java based initiatives :
http://docs.codehaus.org/display/continuation/Home
http://jakarta.apache.org/commons/sandbox/javaflow/
Also, there is a recent discussion about continuations implementations in Spring Web Flow and Rife here.
So there are people trying to see continuation at JVM level and others doing it already for specific use cases, mainly web flows.
From DeveloperWorks article:A second big hurdle is that of how and where to store continuations... We can also store them on the server side, which is what I did in the sample application, but then we have to worry about issues like garbage collection and replication across cluster nodes...
In my opinion, this is not a really a big issue nowadays since we could classify the continuation "stack" to be saved as a transient data. Cameron P., the way is now clear to you here ;)
An for continuations at JVM level, I think is too simplistic to say we need JUST continuations. THe impact of doing this is sufficient to consider a lot of other aspects and do a rework of core aspects of current JVM. Consider this, for example. Not to mention JVM issues at client side, where we do have some non standard but interesting attempts to provide solutions like this.
Humm, I forgot to say: I like continuations. -
Sam Ruby on Continuations for Curmudgeons[ Go to top ]
- Posted by: Rodolfo de Paula
- Posted on: April 14 2005 17:45 EDT
- in response to Rodolfo de Paula
An for continuations at JVM level, I think is too simplistic to say we need JUST continuations.
I meant we do have to think in a broader context since any new feature can have a very negative impact to some other existent or important future feature, after all JVM is too critical to all Java industry. So then perhaps we could realize this is simply unrealistic to ask today (new feature x or y in core JVM). -
Continuations in Cocoon[ Go to top ]
- Posted by: Ralph G.
- Posted on: April 15 2005 01:37 EDT
- in response to Rodolfo de Paula
Sam mentions Cocoon but doesn't provide much of an example. Here is one from the Cocoon web site. Advanced Control Flow. -
Continuations in RIFE[ Go to top ]
- Posted by: Geert Bevin
- Posted on: April 15 2005 03:09 EDT
- in response to Rodolfo de Paula
In RIFE (similarly to Cocoon) we have adopted a continuations style that doesn't mandate their use throughout the whole web engine (which is what Seaside does iirc). There are a number of situations where continuations make your life easier, however there are even more situations where they don't feel natural in a web application. The solution continuations solve best is one where you have a multi-step 'island of functionality' that does one particular thing on its own and that shouldn't be committed to the backend before the final step is finished. These are typically a wizard, a game, a multi-page admin intervention, a survey, ...
You can find a presentation about RIFE continuations at java.net. For more information, feel free to browse some sources or read our wiki pages about it. -
Sam Ruby on Continuations for Curmudgeons[ Go to top ]
- Posted by: Cameron Purdy
- Posted on: April 15 2005 07:43 EDT
- in response to Rodolfo de Paula
Some Java based initiatives..
It would be possible for Java to support language-level continuations with a special sub-class of Throwable, e.g. Continuable. The "yield" equivalent would be to construct the continuable object, which would capture the current frame state (on up the chain of execution frames), throw the object, and let it get caught by an outer frame that is expecting the object to be thrown. A method on the continuable object would allow continuation to be triggered, re-assembling the necessary frames, etc.
The question as to the runtime cost .. no idea on that one.
Peace,
Cameron Purdy
Tangosol, Inc.
Coherence: Cluster your POJOs! -
Sam Ruby on Continuations for Curmudgeons[ Go to top ]
- Posted by: Geert Bevin
- Posted on: April 15 2005 10:52 EDT
- in response to Cameron Purdy
Some Java based initiatives..
It would be possible for Java to support language-level continuations with a special sub-class of Throwable, e.g. Continuable. The "yield" equivalent would be to construct the continuable object, which would capture the current frame state (on up the chain of execution frames), throw the object, and let it get caught by an outer frame that is expecting the object to be thrown. A method on the continuable object would allow continuation to be triggered, re-assembling the necessary frames, etc.The question as to the runtime cost .. no idea on that one.
This is very similar to how it's done in RIFE. For the assembling, bytecode modification is needed though since you can't introspect the local variable stack. To reassemble, the only way is to jump through the code again, starting from a known entry point and skipping all parts that have already been executed. -
Thread base implementation[ Go to top ]
- Posted by: Emmanuel Pirsch
- Posted on: April 15 2005 12:52 EDT
- in response to Cameron Purdy
Look at the comment I posted (http://www.intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons) on his blog... I provide a simple way to do it in Java by using a thread to keep the continuation stack frame.
This is proof of concept level... An it does not address the eventual pesistence of the stack frame. -
Thread base implementation[ Go to top ]
- Posted by: Geert Bevin
- Posted on: April 15 2005 17:22 EDT
- in response to Emmanuel Pirsch
Thread-based implementation can't work in a web environment since you typically hijack the thread and it can't be used by other users anymore. For performance and scalability reasons, threads have to be released as soon as a request terminates. -
Thread base implementation[ Go to top ]
- Posted by: Emmanuel Pirsch
- Posted on: April 15 2005 21:17 EDT
- in response to Geert Bevin
Did you check the code?
The continuation stack frame is kept in a new thread... It will not consume and/or block any thread responding to a request.
The only time the request thread will block is when calling the continuation doit() method. And it will block until the continuation calls the yield() method or when it's execute() method exits (however, there is a bug the sample... If the execute method returns normally (without a yield()), it's returned value will not be returned by the doit() method). This is no more different than the thread method calling some ordinary method in an ordinary object.
The example is fairly simple and was done in less than 30 minutes. But it does prove that continuation can be done without relying on new features in the VM. The only thing that this proof of concept lack is that the continuation stack frame cannot be serialized because a thead cannot be serialized. Only attribute of the continuation could be serialized.
This mean that you cannot easily provide failover of continuation based on thread on a cluster without some other mechanism (think bytecode manipulation).
Other than that, this demonstration is entirely fit for a web application. -
Thread base implementation[ Go to top ]
- Posted by: Geert Bevin
- Posted on: April 16 2005 04:14 EDT
- in response to Emmanuel Pirsch
You're right, Emmmanuel, I'm sorry, I didn't read your code and jumped to conclusions. The real difficulty with implementing native Java continuations is to make them work without changing any code and simply adding a simple statement (pause()) in RIFE. The execution stack and local variable stack needs to be retrieved automatically at that point it time and later restored. The JVM can't do this as of now.
Your implementation requires changing the code by extending a Continuation thread class which spawns a new thread each time it's used, but that could be acceptable. However, in a web application there are also other needs, like the possibility to use the back/forward button and the obtain the continuation that was active at that particular point. This means that you need to start cloning or serializing continuations contexts and keep track of which one to use where. I don't think Java can clone thread instances in wait state with the complete local variable stack and execution frames. So the need of thread serialization is not only there for failover.
What you in fact implemented is a solution for only the latest continuation in a continuation tree, each previous continuation in the tree is lost when you go to the next, while normally continuations allow you to keep the whole tree available and reuse any continuation of it. Taking the quote from the developerworks article: "A continuation is a saved snapshot of the executable state of a program at any given point in time. It is possible to restore this state and restart the execution of the program from that point onward, such that the stack trace, all the local variables, and the program counter can reclaim their old values."
Your implementation doesn't take care of the 'saved' (but you said that yourself already). -
Thread base implementation[ Go to top ]
- Posted by: David Waddell
- Posted on: April 18 2005 12:16 EDT
- in response to Emmanuel Pirsch
is this not just over complex, twisting the language to support a 'yield' keyword it doesn't have ?
The fib could be implemented like this :
private static Continuation fib= new Continuation() {
private int i=0;
private int j=1;
public Object doIt() {
int tmp=j;
i= j; j= i+j;
return new Integer(tmp);
}
}
};
The thread doesn't give anything to the solution. You're using the heap to store state (i,j), inside the object itself, not inside the frame. -
Still not quite convinced[ Go to top ]
- Posted by: Cedric Beust
- Posted on: April 18 2005 14:37 EDT
- in response to David Waddell
I posted a few thoughts (and doubts) on my blog:
http://beust.com/weblog/archives/000272.html
Somebody pointed out in the comments that despite what the article says, C# doesn't support continuations, only closures. The "yield" keywords certainly adds to the confusion.
--
Cedric -
RE: Still not quite convinced[ Go to top ]
- Posted by: Geert Bevin
- Posted on: April 19 2005 00:56 EDT
- in response to Cedric Beust
As a reply to Cedric's post I recorded a video to show that continuations can be debugged with a regular Java debugger when using the RIFE framework, which offers native web continuations in Java.
http://rifers.org/blogs/gbevin/2005/4/18/debugging_continuations_in_rife -
Thread base implementation[ Go to top ]
- Posted by: Emmanuel Pirsch
- Posted on: April 21 2005 09:18 EDT
- in response to David Waddell
is this not just over complex, twisting the language to support a 'yield' keyword it doesn't have ? The fib could be implemented like this :private static Continuation fib= new Continuation() { private int i=0; private int j=1; public Object doIt() { int tmp=j; i= j; j= i+j; return new Integer(tmp); } } };The thread doesn't give anything to the solution. You're using the heap to store state (i,j), inside the object itself, not inside the frame.
You are absolutely right... The fib function need not to be implemented with a continuation (as Cedric pointed out in his blog, this function is a bad example for the use of continuation).
I just used it in my example because I just wanted to show that it was possible to do it with code very much like the example from Sam Ruby's column (in fact the fib function is almost identical).
However, if the work you need to do between each yield() is different, then my implementation has it's uses.
It does have it's drawbacks too... Using thread just to store a stackframe consume a non negligeable amount of system resources... While these threads will be sleeping most of the time, it does put some load on the OS scheduler. And it may not scale all that well after a few thousands threads. So it's not very appropriate for an application that must support a lot of concurrent users.
Please do remember, that I did that in less time than the time I spent replying to comments in this thread... And it is just a proof of concept. I very doubt that I will use that in a real application. I just had fun doing it. -
Transparent migration of mobile agents[ Go to top ]
- Posted by: Achwamabat Machmabalamat
- Posted on: April 16 2005 08:29 EDT
- in response to Cameron Purdy
I remember this being implemented in an agent framework
around 97/98 with above "keywords".
Basically a program would throw an Exception on go() and
upon reactivation the framework "walked" the methods up
(doing nothing) to the point of interruption.
Incredible hack but impossible to trigger "continuation"
externally...
The Glasgow project (rejected Jsr20) started with
similar goals (on VM level) -
Sam Ruby on Continuations for Curmudgeons[ Go to top ]
- Posted by: Dilip Ranganathan
- Posted on: April 18 2005 09:18 EDT
- in response to Cameron Purdy
Some Java based initiatives..
It would be possible for Java to support language-level continuations with a special sub-class of Throwable, e.g. Continuable. The "yield" equivalent would be to construct the continuable object, which would capture the current frame state (on up the chain of execution frames), throw the object, and let it get caught by an outer frame that is expecting the object to be thrown. A method on the continuable object would allow continuation to be triggered, re-assembling the necessary frames, etc.The question as to the runtime cost .. no idea on that one.Peace,Cameron PurdyTangosol, Inc.Coherence: Cluster your POJOs!
Don Box has an awesome follow up:
http://pluralsight.com/blogs/dbox/archive/2005/04/17/7467.aspx