This is the mail archive of the guile@cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: mod_guile design problems


"Will Hartung" <vft750@home.com> writes:

> I got this from
> http://sourceware.cygnus.com/ml/guile/1999-06/msg00293.html
> regarding making a mod_guile for Apache.
> 
> > I just finished reading "Writing Apache Modules with Perl and C",
> > and got quite some ideas for mod_guile, but i have some basic problems:
> 
> I haven't read this book.

It's quite a good read, actually, though it focuses on the Perl
API. It states that the C api is basically the same, and just
gives a reference for the C functions, but it's not quite that
simple sometimes. Oh well.
The approach helped me since i could see how the C api got
wrapped up in another scripting language, so i had some ideas for
the Scheme API.
 
> > - I want to make smob's for the request_rec, server_rec and
> >   conn_rec structures. Those are actually automagically destroyed
> >   by apache when it's done with it. I have no idea how to handle
> >   this - mod_guile modules can of course store the smob's
> >   wherever they like, and access them even after the real ones
> >   have vanished. sadly, apache does *not* provide a clean way to
> >   register "cleanup"-functions for these structures.
> 
> But, in general, if you want to be sloppy

Which i don't want to be :] (one of my bad habits, it seems)

> In reality, I would imagine that the *_recs are allocated from memory pool
> of the request, and therefore implicitly destroyed when the request is
> completed.

I guess so too. I managed the issue by marking the request_rec smobs
invalid in the cleanup stage. All references will throw an error
if the smob is marked invalid.

> > - Apache uses it's own type of FILE pointers, BUFF's.
> >   There seems no way to wrap a BUFF into a guile port and lateron
> >   retrieve the BUFF from the port.
> 
> You shouldn't have any problem wrapping a port around these BUFFs. The issue
> here (to me) is that HTTP requires that the size of the content that is
> being sent be known in advance, whether its being sent in a single pulse, or
> in "chunked" mode.

Nope. Content-Length is not a required header.
My current approach is to make the request_rec's themselves as
ports. Writing them will buffer the written stuff until they're
flushed, then the headers are sent and the accumulated stuff is
sent. After that, each writing call will directly call the
ap_rwrite function.

> > - Memory pools. I haven't found any use for memory pools in Guile
> >   since it's already Garbage Collected. I just need some logic to
> >   find an appropriate pool for those functions that require one.
> >   (e.g. ap_escape_shell_cmd - i'll copy the result so it can be
> >   stored in guile independently of the pool)
> 
> Yeah, you can pretty much punt on the memory pools, they're just as a
> benefit to the module developer. You don't NEED to use them. They're primary
> use is for the C coders to use them rather than malloc(1) so that they can
> worry less about memory leaks. Of course, the C++ guys are pretty much left
> out in the cold, but that's pretty much a default state for them anyway.

I'm mostly ignoring them by now. A few problems persist for
functions like ap_server_root_relative which ask for a pool. I
implemented my own function to do that, though, using
scm_must_malloc - but just copying the code isn't the best
approach :(

> > More or less unrelated to this, i'm also searching for the new
> > Environment specification (i've lost my local copy). I wonder
> > wether it'll be possible to mark an environment as "read-only",
> > e.g. that a set! will not affect that environment or any of it'sparents.
>
> Here are some things that you may want to consider: (note, I made a related
> posting about this in comp.lang.scheme, and someone suggested I come here).
> 
> First, as mentioned, Apache runs in two different modes. It's forked on UNIX
> and threaded on NT. And it seems that for performance reasons, they want to
> take Apache towards the threaded model.

Therefore we should just assume the server to be threaded, since
that will come anyways, and it'll spare us some hassles when it's
converted.

>[forked model has problems sharing data]

Hmm.
How about a "Shared Memory Environment" guile environment type,
that is, an environment that resides in shared memory and can be
"docked to" from different processes? This might actually be a
nice idea for the standard guile distribution...

> Of course, in the threaded model it is completely flipped
> around. Everything is shared. So you need to be concerned about
> a "read only" environment, and you need to be concerned with
> resource sharing (at least managing it).

Hmm.. Shouldn't Guile's thread support handle this?

> I would come up with a scheme layer to the CGI, have the scheme
> request handle the POST and GET stuff, creating an assoc list
> or whatever, then make the HTTP-PORT the *current-output-port*
> and jump to your script from there. That way you can write your
> scheme like a CGI program, and test your scheme like a CGI
> program. Once you can duplicate that functionality, then I'd
> tackle the embedded scheme in HTML project.

I want to be able to write apache modules in Scheme, not just
content handlers :)
And the way i'm planning the latter, they'll be done like this:
- You set a Guile reader function for a specific type.
- The file of that type will be read by this function.
- The resulting Scheme code will be eval'd in a CGI environment -
  each reader function is responsible for setting up the
  necessary environment stuff outside the CGI specification.

This approach allows us to do e.g. "GuileSetReader .tcl read-tcl"
or something like this, and have faster Tcl CGI's (of course they
would have much more functions to work with the request).
The current request-rec is (current-output-port) or
(current-input-port). 

I actually implemented a cache-load function which loads a file
into a (lambda () ...) so the eval'd version will just give a
function that, when eval'd, will result in the same actions as
loading the file would (cache-load handles this transparently,
even reloading if the mtime changes).

The only problem i see here is that multiple defines in the
beginning of the file won't work as expected (the differences of
multiple defines in a function to multiple defines in the top
level are one of the very, very few warts in Scheme)
	-forcer

-- 
((email . "forcer@mindless.com")       (www . "http://forcix.cx/")
 (irc   . "forcer@#StarWars (IRCnet)") (gpg . "/other/forcer.gpg"))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]