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

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/.

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 Haines

···

On Wed, 16 Apr 2008, Alexey Petrushin wrote:

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

Alexey Petrushin wrote:

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

Have you looked at Michael Neumann's "Wee" Web framework?

···

--
James Britt

"I can see them saying something like 'OMG Three Wizards Awesome'"
   - billinboston, on reddit.com

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

···

On Apr 16, 2008, at 10:08 AM, khaines@enigo.com wrote:

On Wed, 16 Apr 2008, Alexey Petrushin 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.

James Britt wrote:

Alexey Petrushin wrote:

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

Have you looked at Michael Neumann's "Wee" Web framework?

http://www.ntecs.de/projects/wee/doc/rdoc/
http://rubyforge.org/projects/wee

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:

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/.

Alexey Petrushin 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