[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: mod_lisp for guile
Re: mod_lisp for guile
Mon, 19 Sep 2005 10:46:25 -0400
Mozilla Thunderbird 1.0.2 (X11/20050317)
Neil Jerram wrote:
> Alan Grover <address@hidden> writes:
>>* Should I remove the thread-creation stuff and stick simply to mod_lisp
> I don't understand what the mod_lisp protocol is, so can't really
> comment. I'm interested in the architecture though - can you describe
> it (or point me to reference)?
Mod_lisp is a module for the Apache web-server. Via a simple
configuration, you can have Apache "forward" a request to a separate
process. The mod_lisp protocol is very simple.
The mod_lisp home is:
So, instead of writing a HTTP server, you write a mod_lisp server which
is simpler. You can take advantage of all the features of Apache (ssl,
filtering, rewriting, access control, aliasing, etc.).
Or, instead of writing your web-application as a CGI, your mod-lisp
server is a separate process that is always running. Thus, you avoid the
delay of starting a process for each CGI, instead starting it once as a
daemon. You could use threads to handle the requests, possibly reducing
resource usage, and allowing simple inter-thread communication, but
requiring consideration of races/locks. Forking could also be used.
>>* Should I provide an interface to integrate with TTN's www-guile?
> How would that help? (Genuine question.)
Several people have produced modules/code to help handle the CGI
interface. TTN's, for example, parses the environment variables to
produce a scheme friendly interface, and parses the query-string. Such
modules have done the work to be standards compliant/complete.
So, I'd have to figure a clever way for TTN's www-guile to see the
mod-lisp data, or propose a patch that integrates with mod-lisp.
>>* How bad is the user-interface?
> Do you mean the programming interface? (By UI I'd normally understand
> something like a window or a command line, and AFAICS mod_lisp doesn't
> have either of these.)
Bit of a slip there. Literally the "user's interface", the user being
the programmer. On a good day, I would have said API.
>>* What do you think of providing a lazy-list of requests, rather than
>>the current technique of passing control to a
> Don't understand enough yet to know! Please explain further.
The interface in the first release is a function that loops, calling
your function for each request. So, it kind of takes over. It occurred
to me that there might be more polite ways of working. At the very
least, there should be mechanisms that impose the least policy.
So, I'm going to work on (some of) the following interfaces:
* (f port) -> headers-as-alist, does nothing else
* (f port header-constructor) -> calls (header-constructor k v) for each
header, does nothing else (maybe like fold?)
* (f port) -> lazy list of (k v), suitable for whatever map/fold you
want to do.
* (f port) -> (headers content-length), convenience for post-data
* Same, plus the header-constructor
* (f port ...) -> returns a lazy list of something like (headers port),
(one element for each request, blocking).
* Perhaps versions of the above that return something like
(request-header-port ; returns pairs (k v) till '()/#f
request-content-port ; returns content part till eof-object
response-header-port ; takes only pairs (k v)
response-content-port) ; typical HTML body
Where request-content-port would only return up-to content-length bytes,
and response-content-port constructs the content-length header if needed.
Lazy-lists (see "delay" and "force") are things that act like a list,
but where the next-element isn't calculated until you "look" at it (this
is only one kind of lazy-list, but close enough).
So, assuming I provided lazy-mod-lisp:
(define lazy-results (lazy-mod-lisp socket-port))
(pair? lazy-results) ; -> #t. maybe not, I'd have to check
; actually does the work to figure out first mod-lisp request. could
(define first (car lazy-results)) ; might need "force"
; Handle the request (and to loop here)
(set! lazy-results (cdr lazy-results)) ; never blocks!
(set! first (car lazy-results)) ; might need "force"
; Loop back to my-handle-request (till '() )
; Could/will block, waiting for each mod-lisp request
(for-each my-handle-request lazy-results)
You might have to call "force" on "first", I'd have to check (see
forthcoming version of my mod-lisp for guile/scheme).
>>* Do you want to see a SRFI that provides _just_ the mod_lisp
> Presumably you mean a SRFI defining a common Scheme API that people
> could use to write code that plugs into your mod_lisp engine? (I
> guess I'm missing the architecture again here.)
Right, convenient API to the scheme side of the protocol.