# Continuation in web (Seaside clone)

**URL:** <https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947>\
**Category:** Ruby\
**Created:** [April 16, 2008, 2:41pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947 "2008-04-16T14:41:10Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 16, 2008, 2:41pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/1 "2008-04-16T14:41:10Z")

</div>

Hello!

IN SHORT (by some example):

There is a web application, and two ‘pages’ - ‘View’ and ‘Editor’. And  
when i press ‘Edit’ button on the ‘View’ it should:

- Freeze current execution (callcc {bla-bla})
- Give control to ‘Editor’
- User fill data in ‘Editor’
- ‘Editor’ return entered data and control back to ‘List’  
(continuation.call data)
- Friezed execution resumes

THE PROBLEM:  
I implement this the same way as in Seaside, and it seems to should  
works, but it throws:  
“Caught RuntimeError: continuation called across threads”

Probably, because WebServer runs each request in a new thread. Do you  
hawe any idea how this can be solved?

Thanks!

DETAILS:  
In pseudo code:

class Editor \< Form  
def initialize  
data = TextField.new self, ‘’  
FormButton.new(self, ‘Save’) {answer data.text}  
end  
end

class View \< Panel  
def initialize editor  
view= Label.new self, ‘Some initial value …’  
Button.new(self, ‘Edit’) {view.text = call(editor)}  
end  
end

class MySuperApp \< Panel  
def initialize  
View.new(self, Editor.new)  
end  
end

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 16, 2008, 5:27pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/2 "2008-04-16T17:27:28Z")

</div>

Done! 🙂  
I founded an ugly solution (closures instead of continuation). It works,  
looks like:

All other components are the same as earlier, i just a little changed  
the ‘View’.  
To complete edition user should 3 times enter something in Wizzard-like  
dialogs.

WITH CONTINUATION IT SHOULD LOOKS LIKE:  
class View \< Panel  
def initialize editor  
view= Label.new self, ‘Value’  
Button.new(self, ‘Edit’) {  
first = call(editor)  
second = call(editor)  
third = call(editor)  
view.text = first+second+third  
}  
end  
end

WITH MY UGLY SOLUTION IT LOOKS:  
class View \< Panel  
def initialize editor  
view= Label.new self, ‘Value’  
Button.new(self, ‘Edit’) {  
call(editor) { |v|  
first = v  
call(editor){ |v|  
second = v  
call(editor){ |v|  
third = v  
view.text = first+second+third  
}  
}  
}  
}  
end  
end

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 16, 2008, 6:25pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/3 "2008-04-16T18:25:26Z")

</div>

Alexey P. wrote:

> Done! 🙂  
> I founded an ugly solution (closures instead of continuation). It works,  
> looks like:

Have you looked at Michael N.'s “Wee” Web framework?

–  
James B.

“I can see them saying something like ‘OMG Three Wizards Awesome’”

- billinboston, on [reddit.com](http://reddit.com)

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 16, 2008, 7:16pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/4 "2008-04-16T19:16:37Z")

</div>

James B. wrote:

> Alexey P. wrote:
> 
> > Done! 🙂  
> > I founded an ugly solution (closures instead of continuation). It  
> > works, looks like:
> 
> Have you looked at Michael N.'s “Wee” Web framework?

[http://www.ntecs.de/projects/wee/doc/rdoc/](http://www.ntecs.de/projects/wee/doc/rdoc/)  
[http://rubyforge.org/projects/wee](http://rubyforge.org/projects/wee)

Regards,

Michael

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 16, 2008, 11:03pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/5 "2008-04-16T23:03:40Z")

</div>

On Apr 16, 2008, at 10:08 AM, removed\_email\_address@domain.invalid wrote:

> slow. You can get 80% of the love with none of the pain by using  
> techniques not based on continuations.

Yes, as the author of Borges, try Wee, as mentioned elsewhere. Wee  
actually works.

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 16, 2008, 7:08pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/6 "2008-04-16T19:08:59Z")

</div>

On Wed, 16 Apr 2008, Alexey P. wrote:

> THE PROBLEM:  
> I implement this the same way as in Seaside, and it seems to should  
> works, but it throws:

Just FYI, but there is Borges, [http://borges.rubyforge.org/](http://borges.rubyforge.org/), which was  
based on Seaside 2.

However, continuations in Ruby tend to leak RAM, and tend to be slow.  
You  
can get 80% of the love with none of the pain by using techniques not  
based on continuations.

Kirk H.

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 17, 2008, 12:26pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/7 "2008-04-17T12:26:36Z")

</div>

Wee and Borges frameworks.

Yes i goggled it about 3 months ago but sadly don’t found any  
ready-to-show samples or sites running on these frameworks and go  
further. ☹

Yesterday i investigated it in more details, looks cool, and my solution  
looks very close to it, but now i almost finished my prototype 🙂

Main difference is in HTML builder(renderer?), i use Swing(Java) like  
API (i.e. no HTML/HTTP at all, just Labels, Panels, Buttons,  
LayoutManagers and so on).

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 17, 2008, 2:01pm UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/8 "2008-04-17T14:01:36Z")

</div>

Alexey P. wrote:

> As i understood:
> 
> - It’s better not to use continuation, especially in multi threads.
> - There is a way to imitate it, like code sample below:
> 
> …  
> call MessageBox.new(“Delete?”){|response|  
> if response  
> call MessageBox.new(“Are you sure?”){|response2|  
> delete if response2  
> }  
> end  
> }  
> …

Correct. Wee uses one thread per session (i.e. user) and keeps this  
thread alive. This is required at least when using continuations,  
because you can’t continue a continuation from another thread.

With continuations, you could write it as:

delete if call(MessageBox.new(“Delete?”)) and  
call(MessageBox.new(“Are you sure?”)

That is a lot clearer!

But, continuations have some downsides (that applies to  
Matz’ Ruby interpreter):

- You can’t marshal them.
- Single-threaded (per session/user).
- They might leak memory.

> Thanks for advices! 🙂

You’re welcome!

Regards,

Michael

---

<div class="post-metadata">

**Author:** ![axyd80](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/82dd89/32.png) [@axyd80](https://www.ruby-forum.com/u/axyd80)\
**Post date:** [April 17, 2008, 11:51am UTC](https://www.ruby-forum.com/t/continuation-in-web-seaside-clone/134947/9 "2008-04-17T11:51:50Z")

</div>

As i understood:

- It’s better not to use continuation, especially in multi threads.
- There is a way to imitate it, like code sample below:

…  
call MessageBox.new(“Delete?”){|response|  
if response  
call MessageBox.new(“Are you sure?”){|response2|  
delete if response2  
}  
end  
}  
…

Thanks for advices! 🙂
