iowa sounds a lot like fastcgi. besides from being a ruby
application with all that comes with that, how does it differ?
- is there an object pool, or one responder object?
- does session affinity exist?
- how exactly would one use it 'with' fastcgi?
Iowa is a framework for creating web apps and dynamic web content. It's
only affiliation with FCGI is using FCGI as a mechanism for transfering the
request from the web server to the Iowa process.
BROWSER -------> WEBSERVER --[REQUEST_TRANSPORT]---> IOWA
^ | ^ |
> > > >
----------------- ---------------------------------
The browser sends it's request to the web server. Through some mechanism,
the web server identifies that the request should be handled by Iowa, and
transfers the request to the Iowa process. Iowa handles the request,
returning content to the webserver which then returns it to the browser.
The mechanism that I typically use for the webserver to identify requests
that should go to the Iowa process is a mod_ruby handler. One uses regular
Apache directives like <Location> to tell Apache what should be subjected to
the handler's examination. The handler, in turn, uses a simple file of
paths such as:
/
/index.html
/my_application
/images/project_gannt_chart.svg
to know what it should pass on to Iowa and what it should simply let fall
through for Apache to handle itself.
The FCGI or plain old CGI support replaces the mod_ruby handler. If one
does not run mod_ruby, one can use web server directives to decide what
requests should go to Iowa. <Location>, <Directory>, mod_rewrite rules,
whatever. Those requests get to the Iowa process by going through a CGI or
FCGI program that basically just constructs an Iowa::Request object (which
is like a lightweight serializeable Apache::Request) and sends it to the
Iowa process's communication's socket. Iowa handles the request, generating
the content, and returns it back down the socket to the CGI or FCGI program,
which then in turn sends the content back to the webserver as its own.
The Iowa process is multithreaded. When a request comes into it, it
dispatches a thread to handle the request. In a nutshell, this handler
identifies which component the request needs to go to and passes
responsibility to the component. Each piece of content, whether it be a
full web page or just a piece of a page such as a header, footer, or
navigation bar/box, is a component, and each component is an object. Each
component is constructed of a layout section and a code section, with an
optional bindings section.
An example of layout:
<div class="inputTable">
<form oid="save">
Name: @user<br/>
Email: <input type="text" oid="email" size="40" maxlength="80"><br/>
Comment: <textarea rows="5" cols="65" oid="text"/><br/>
<input type="submit" oid="save" value="Save">
<input type="submit" oid="cancel" value="Cancel">
</form>
</div>
<table class="resultsTable">
<tr>
<th>Name</th>
<th>Email</th>
<th>Comment</th>
</tr>
<repeat oid="entryList">
<tr>
<td>@entry.name</td>
<td>@entry.email</td>
<td>@entry.text</td>
</tr>
</repeat>
</table>
<Footer oid="footer"/>
It's just plain old HTML, for the most part. The only difference is that
some of the tags have an oid= attribute in them. OID stands for object id,
and it's existence is the cue to Iowa that Iowa needs to step in and do
something dynamic there. In addition to that, there are some pieces of text
that are prefaced with an @, such as @user and @entry.name. @ means that
what follows is the name of a method to call. What is returned from the
method call will be inserted into the content at that point.
The only other piece that differs from a static HTML document is the
<repeat> tag. Iowa doesn't allow code within the layout, so for doing
things like looping through a list of values or conditionals, it employs a
very small set of additional HTML-like tags. That <repeat> tag tells Iowa
that it needs to look for a binding, entryList, that should define a list
and an iterator.
In the code section, the binding for entryList looks like this:
entryList {
item = entry
list = entries
}
'entries' is a method that returns an array to iterate through.
def entries
@db.transaction do
@db.roots.sort.collect {|k| @db[k]}
end
end
And 'entry' is just an accessor:
attr_accessor :entry
A quick sidenote here. There are some tags, such as <ul>, that Iowa knows
are tags that inherently deal with lists of stuff. If one were to do this:
<ul oid="entryList">
<li>@entry.name</li>
</ul>
Iowa would know that you mean for that <ul> to iterate over the entryList.
<table> is another tag like this. If I took out the <th> tags in the above
table, I could have written it like this:
<table oid="entryList">
<tr>
<td>@entry.name</td>
<td>@entry.email</td>
<td>@entry.text</td>
</tr>
</table>
The only other nonstandard item in there is the <Footer/> tag. A Footer is
a seperate component that defines the standard footer for the site. That
tag just includes an instance of the Footer component into this one.
The end result is that it is very easy to contruct applications or other
dynamic content. You write all of the content layout in a standard way.
You can even use a WYSIWYG tool for this if you want. Then you use Ruby to
write the meat. Iowa takes care of making sure that form inputs get placed
in the proper writers or accessors, and takes care of session management and
all of the general administrative tasks, so all the developer or developers
have to do is concentrate on creating the substance.
My goal with Iowa is for the framework to stay out of my way as much as
possible. It is a LOT like Rails in intent, but very different in
implementation. It straddles the seperation of content from code somewhere
between Rails and CGIKit. Rails lets one embed code in the content. CGIKit
is very zealous in requiring a binding to create an additional level of
indirection between content and code. Iowa keeps the code out of the
content, but has a few code-like markup tags and allows direct method calls
from within the code. One of the coming additions, again thanks to David
Naseby for writing the seed to get it started, is the ability to basically
inline programmatically generated images and things of that nature into a
page generated by Iowa.
The genesis of this was David's desire to display a Gannt table generated
with the SVG library from Sean Russel. He hated the idea of saving it off
to a temporary file just to display it once, so he hacked Iowa so that he
could inline it. A method call generates the SVG image and Iowa takes care
of making sure that the URL in the content, when accessed, invokes that
method. So the SVG image gets generated on the fly without ever having to
be stored on disk, but as the developer, all you have to do is provide the
method to generate the SVG. It's pretty neat.
Like I mentioned earlier, I've been using it for more than two years on a
wide variety of business applications and complete web sites, and I continue
to use it and develop on it because it's just plain fast and easy to get
results.
Now that Iowa can be used with WEBrick, that opens up a whole new avenue of
possibilities for me, too. It's trivial to start a WEBrick + Iowa server,
which makes it fantastic for testing things and for working on developing an
Iowa application or Iowa powered web site, even if one doesn't intend to use
WEBrick in production to serve the application or site. And with exerb I
should also be able to write a complete web app including all of the support
content such as images and other static content and wrap that all up as a
single executable that can just be installed and executed.
Wow. This ended up being long. Hopefully it helps explain better than I
did yesterday just what Iowa is, though.
Thanks,
Kirk Haines
···
On Sun, 8 Aug 2004 22:41:20 +0900, Ara.T.Howard wrote