O''''Reilly Network For Information About''''s Book part 25 - Pdf 17


8.2. Continuations
You've probably played video games. Think of a continuation as a save game
feature. As you're playing your game, you save your current game. You can feel
free to take your chances with the monster control center. If you die, you simply
restore the game. Said another way, a continuation is a snapshot of a point in time.
Continuations let you save the system's state (in the form of an execution stack) in
one place, and then return to that state on command.
Since I've already introduced Ruby's syntax, I'll first show you continuations in
Ruby, where continuation syntax is clean and precise. Then, I'll show you Seaside,
the most popular continuation-based server, in Smalltalk.
In Ruby, a code block defines the universe for the continuation. You'll use a
continuation object to hold the execution state, consisting of the execution stack.
You'll later invoke a call method on the continuation object to restore the system
state, replacing the current execution state, including the call stack, with the one in
the continuation object. The call returns execution to the point immediately after
the code block. From Ruby's perspective, you're conceptually letting your
execution state jump back in time.
8.2.1. The Syntax
In Ruby, you get a continuation by calling the callcc method on Kernel and
passing it a code block. This block does nothing with the continuation but print its
object identifier:
irb(main):001:0> callcc {|continuation| puts continuation}
#<Continuation:0x28c2dd8>
This passive little program does more than you think it does. The argument called
continuation is a powerful little gem that has the whole execution context,
with variable values and the entire call stack, at the time that you called callcc.
Look at it as a saved game, or a frozen moment in time. You can return to that
moment in time. Specifically, Ruby will return to execute the statement
immediately after the continuation block by calling the continuation. Here's a
trickier continuation example:

the block to the way they were when you made the continuation call. So, this
program:
1 def loop
2 for i in 1 5 do
3 puts i
4 callcc {|continuation| return continuation} if i= =2
5 end # cont.call returns here
6 return nil
7 end
8
9 puts "Before loop call"
10 cont=loop( )
11 puts "After loop call"
12 cont.call if cont
13 puts "After continuation call"
gives you this result:
>ruby continuation.rb
Before loop call
1
2
After loop call
3
4
5
After loop call
After continuation call
So, we were able to exit the loop when something happened and return to the loop
on command. Since continuations are so alien, let's look at this example in a little
more detail. It's not too bad to read, once you know what's hap
pening. Line 4 saves

 Execute lines 13 and 15. Skip line 14 because cont is nil.
This continuation example shows you a few nice capabilities. You can take a
snapshot of execution state at some point in time, like we did within the for loop.
You can save that execution state in an object, as we did in the cont object. You
can then return to the execution state stored in a continuation object at any point.
8.2.3. Why Would You Use Them?
You might first think that continuations are the most useful when you want to
break logical control structures, as in implementing a break for our for loop, or
processing exceptions. For the most part, though, you want to think "suspend and
resume." Continuations are marvelous in these kinds of scenarios. Cooperative
multitasking lets one program voluntarily relinquish control to another application,
and resume at a later date. This problem is remarkably easy to solve using
continuations. A subtler use involves communication. When you've got an
application that spans multiple computers with synchronous request/response
communication, you often want to suspend control until the remote system
responds. When you need to scale this solution, suspending control while you wait
frees the system to handle other requests. The system can conveniently resume
your application without disruption when the remote system responds, simply by
calling a continuation. 8.3. Continuation Servers
You can probably begin to see why continuations might be interesting for web
servers. If you want to look at a web application as one continuous application with
suspend/resume breaks in between to communicate with the user, it makes more
sense. While waiting for user input in the form of an HTTP request, the web server
could simply store a state, stash the continuation object away in the HTTP session,

platforms, industries, and domains.
What's wrong with
current web
development
models, like the
Servlet model?
GV: There are two big problems. I'll start
with the most obvious. When I did
mainframe programming, I would build a
screen of information mixed with form
fields, and push it out to a 3270 terminal.
The program wouldn't hear from the
terminal again until the user hit Enter.
Sound familiar?
In the mainframe days, the program got to
pause and wait on the user's submission.
Web programming is actually worse,
because in the interest of scaling to
thousands of users (as opposed to
hundreds), the program is asked to forget
as much as possible between each
interaction so that each submission can
stand alone. The stateless nature of the
web programming model forces
programmers to manually manipulate,
store, and retrieve the program state at
every stage. Web frameworks help some,
but programmers still have to consider
carefully how to deal with each piece of
state. One mistake and we get web


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status