[Web-SIG] Web Container Interface
ianb at colorstudy.com
Fri Jan 23 16:31:10 EST 2004
Phillip J. Eby wrote:
> It's waiting for me to have enough spare cycles to write another draft.
> I've been pretty bogged down with "real work" lately.
Real work is no fun. It's the damn material needs and desires that are
>> The biggest issue I see with it is that the container needs to be
>> passed as one of the arguments to runCGI. This allows for greater
>> integration of the application and the container.
> But there isn't any functionality the proposal requires of the container
> beyond this. For example, what would a plain CGI container provide? A
> FastCGI container? For a lowest-common-denominator interface, what
> "integration" is possible or needed?
Well, understanding the threading properties of the container or
application for one. We might not be able to define it -- but at some
point we probably want to be able to communicate the situation between
the two. Or stuff about the persistence of the process. Or about the
concurrency expectations of the application. And that's just the
obvious stuff in one situation. There's logging, shared
(container-wide) configuration, authentication, and it goes on and on.
Unless you have a different concept of container and application than
I'm thinking of.
>> Blech... I don't like those terms, because the container's primary
>> responsibility isn't containment, and the application's function is
>> probably more general than a web application's. I'd rather see the
>> container called something like the HTTP Driver, or otherwise
>> indicating that it is the bridge between this simplified CGI
>> interface, and the full HTTP interface. It may provide an HTTP
>> interface, like with Twisted, or it may simply be a bridge to Apache
>> or another server. Container means nothing to me. But I digress...
> Okay. I used container to imply that the application "runs within" the
> container, ala servlet containers and bean containers in Java. But I
> didn't want to call the application a "servlet", since that implies
> long-runningness. OTOH, maybe we *should* call them servlets, since
> only a plain CGI container won't be long-running.
I wonder about the psychological implications of using "servlet", but
otherwise okay ;)
> The Java servlet API has a total of 5 methods: init(), service(),
> destroy(), getServletConfig(), and getServletInfo(). service() is
> essentially runCGI() with request and response objects. From my POV,
> none of the other four are of much use for simple containers, and it was
> specifically intended that the proposal not try to go into the highly
> controversial request/response interface area.
So... it's just confusing to reuse the term "servlet" when it's not
quite the same thing.
>> The interface is sparse, and doesn't allow for things like leaving
>> headers parsed (which is something several containers would prefer).
> I'm not sure I'm following you. As it sits, the proposal *requires*
> parsed headers on output. It's unparsed headers that aren't supported.
Well, I was thinking of the "parsed" representation of headers being a
dictionary, or a list of two-tuples. Systems that speak HTTP directly
will want access to these, so they can do all the CGI-ish stuff
necessary (translate the Status header to the response code, look at
Location). They can re-parse the headers on the way out, or they could
be provided with the headers directly. Seeing as most frameworks
collect the headers directly, it might be nice to save the trouble of
serializing the headers and then parsing them, at least when possible.
>> That's okay, but it would be nice -- even if only in an ad hoc manner
>> -- if applications could query the container about what it is and how
>> it works. To do that we need to pass some sort of reference to the
>> container, even if the nature of that object remains undefined.
> If you could present a concrete use case, it'd be a lot easier to
> understand what a solution might be.
Well, the application may want to share configuration with other
applications (even if it's where-do-I-find-my-configuration-file
configuration). This could be container-wide, so the application could
query the container for that information.
Or, the application may want to know something about the URL layout.
Mmm... which makes me think that PATH_INFO and SCRIPT_NAME need to be
well defined for runCGI, or alternate variables need to be considered.
Does SCRIPT_NAME (and several associated CGI variables, PATH_INFO
included) point to the application, or the container, or what?
The application may want to know if there are any shared services it can
use, like a persistent storage for sessions, or a cron-type service.
Scheduling tasks particularly comes to mind -- it has to be done very
differently depending on the environment. In a long-running threaded
environment you could probably do it yourself. In an async environment
there's a specific callback that's part of the control loop. In a
process-based environment you may have to talk to some parent process.
In a CGI environment... well, you just don't get one there.
>> The other (related) issue I see is the reliance on configuration. One
>> of the goals, presumably, is that frameworks that encompass both
>> container and application (as Webware does) partition themselves more
>> clearly. That's no big deal -- Webware already has a function very
>> like runCGI (Webware.WebKit.Application.dispatchRawRequest), and
>> translating the method signatures is trivial.
>> Unfortunately, the real effort is in allowing it all to be
>> "configured" to work with different backends, or the backend with
>> different applications. This reliance on configuration seems very
>> Java. I hate configuration. A lot. It makes programmers into system
>> administrators, to the detriment of both programmers and system
> I'm not sure I'm following this either. If you prefer to use code to
> connect things, what's wrong with:
> from some_container import Container
> from some_framework import App
> c = Container(
> c.run() # or whatever some_container says you do to start the Container
> ...for arbitrary values of Container and App? If you need to set up
> container-specific settings, we're only talking about adding a few more
> arguments to Container.__init__. And if you need app-specific
> configuration, the same thing is true for App.
> So, I'm not getting what problem you're trying to solve here.
Maybe I'm not entirely sure either. Something's bothering me, though.
I'm having a hard time picturing the use of this proposal to do things
we can't do now, i.e., hooking up things that weren't built with each
other specifically in mind.
> Presumably, a given framework and/or container developer would simply
> create wrapper classes corresponding to Container and App above, using
> options that are relevant to that particular container or framework.
>> Perhaps this richer interface is the sort of thing we should be
>> developing on an as-needed basis, like I would do for Webware, and
>> hopefully as others did the same we'd informally start to agree on
>> what that might look like. And frankly, until this interface *is*
>> developed, I don't think runCGI alone is a useful interface. But it's
>> a place to start.
> And I don't think that you could get anywhere near a common interface
> until you first had something for people to build stuff on. :) When we
> all get tired of writing our 10-line scripts to pass keyword arguments
> to a container and an app (because we're doing the same things over and
> over again), we can always add some shortcuts into a WCI 2.0 API. In
> the meantime, we'll have had the advantage of being able to connect
> things up at all.
That's what I was conceding. We aren't ready to define what those
interfaces will be, but we need to keep in mind that there *will* be
other interfaces, and that the growth of those interfaces is important
to the utility of the WCI. Simply passing in the container as an
argument to runCGI is probably sufficient.
More information about the Web-SIG