Continuation in web (Seaside clone)

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

Done! :slight_smile:
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

Alexey P. wrote:

Done! :slight_smile:
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’”

James B. wrote:

Alexey P. wrote:

Done! :slight_smile:
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://rubyforge.org/projects/wee

Regards,

Michael

On Apr 16, 2008, at 10:08 AM, [email protected] 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.

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/, 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.

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. :frowning:

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

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).

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! :slight_smile:

You’re welcome!

Regards,

Michael

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! :slight_smile: