unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* mod_lisp for guile
@ 2005-09-15 17:25 Alan Grover
  2005-09-16 18:46 ` Neil Jerram
  0 siblings, 1 reply; 12+ messages in thread
From: Alan Grover @ 2005-09-15 17:25 UTC (permalink / raw)


Inspired by Guillaume  Germain on the comp.lang.scheme group, I wrote a
mod_lisp implementation for Guile. Find it at:
https://sourceforge.net/project/showfiles.php?group_id=141512&package_id=163742

I only implemented the mod_lisp protocol, leaving query-string/POST and
HTML utilities for an external package (for example, TTN's www-guile). I
did give in to weakness and provide an optional ability to create a
thread for each request (did you know that "accept" blocks all threads?
Yum.).

It is minimally tested (it has an internal test daemon).

I'd appreciate some feedback:
* Will you use it?
* Should I remove the thread-creation stuff and stick simply to mod_lisp
protocol?
* Should I provide an interface to integrate with TTN's www-guile?
* How bad is the user-interface?
* What do you think of providing a lazy-list of requests, rather than
the current technique of passing control to a blocking-looping-function?
* Do you want to see a SRFI that provides _just_ the mod_lisp protocol?



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-09-15 17:25 mod_lisp for guile Alan Grover
@ 2005-09-16 18:46 ` Neil Jerram
  2005-09-19 14:46   ` Alan Grover
  0 siblings, 1 reply; 12+ messages in thread
From: Neil Jerram @ 2005-09-16 18:46 UTC (permalink / raw)
  Cc: guile-user

Alan Grover <awgrover@mail.msen.com> writes:

> Inspired by Guillaume  Germain on the comp.lang.scheme group, I wrote a
> mod_lisp implementation for Guile. Find it at:
> https://sourceforge.net/project/showfiles.php?group_id=141512&package_id=163742
>
> I only implemented the mod_lisp protocol, leaving query-string/POST and
> HTML utilities for an external package (for example, TTN's www-guile). I
> did give in to weakness and provide an optional ability to create a
> thread for each request (did you know that "accept" blocks all threads?
> Yum.).
>
> It is minimally tested (it has an internal test daemon).
>
> I'd appreciate some feedback:

To be honest, I don't have that much to offer; but I know what it's
like when one posts to the list and gets no feedback at all, so here
goes ...

> * Will you use it?

I don't know.  Currently whenever I want to add a Web interface to
a program, I just knock up the HTTP server infrastructure as part of
that program.  But perhaps that's silly - would advantages would I get
from using mod_lisp instead?

> * Should I remove the thread-creation stuff and stick simply to mod_lisp
> protocol?

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)?

> * Should I provide an interface to integrate with TTN's www-guile?

How would that help?  (Genuine question.)

> * 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.)

> * What do you think of providing a lazy-list of requests, rather than
> the current technique of passing control to a
> blocking-looping-function?

Don't understand enough yet to know!  Please explain further.

> * Do you want to see a SRFI that provides _just_ the mod_lisp
> protocol?

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.)

Regards,
        Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-09-16 18:46 ` Neil Jerram
@ 2005-09-19 14:46   ` Alan Grover
  2005-09-19 21:32     ` Neil Jerram
  0 siblings, 1 reply; 12+ messages in thread
From: Alan Grover @ 2005-09-19 14:46 UTC (permalink / raw)
  Cc: Neil Jerram



Neil Jerram wrote:
> Alan Grover <awgrover@mail.msen.com> writes:
>>* Should I remove the thread-creation stuff and stick simply to mod_lisp
>>protocol?
> 
> 
> 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:
http://www.fractalconcept.com/asp/tC2/sdataQvrZSvEqz7EuDM==/uC2sdataQuvY9x3g$ecX

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
>>blocking-looping-function?
> 
> 
> 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
block!
	(define first (car lazy-results)) ; might need "force"

	; Handle the request (and to loop here)
	(my-handle-request first)

	(set! lazy-results (cdr lazy-results)) ; never blocks!
	(set! first (car lazy-results)) ; might need "force"

	; Loop back to my-handle-request (till '() )

Or,
	; 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
>>protocol?
> 
> 
> 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.


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-09-19 14:46   ` Alan Grover
@ 2005-09-19 21:32     ` Neil Jerram
  2005-09-20  3:24       ` Alan Grover
  0 siblings, 1 reply; 12+ messages in thread
From: Neil Jerram @ 2005-09-19 21:32 UTC (permalink / raw)
  Cc: guile-user

Alan Grover <awgrover@mail.msen.com> writes:

> 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:
> http://www.fractalconcept.com/asp/tC2/sdataQvrZSvEqz7EuDM==/uC2sdataQuvY9x3g$ecX
>
> 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.).

Yes, this makes a lot of sense.  Thanks for your patience in
describing it, and for the pointer.

It seems to me, though, that there is nothing especially lispy about
the module (mod_lisp) which runs inside Apache.  Presumably the Apache
side of the protocol could be implemented in any language, or could be
provided "native" by Apache itself?

Is the form of the protocol itself lispy?  (I.e. parenthesised and
readable using read.)

> 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.

How would using threads reduce resource usage?  Otherwise this all
makes sense.

>>>* 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.

So you mean that if someone has already written an HTTP request
handler procedure for use with www-guile, it ought to be possible to
reuse exactly that same procedure with your mod-lisp also?  Sounds
good to me.

>>>* What do you think of providing a lazy-list of requests, rather than
>>>the current technique of passing control to a
>>>blocking-looping-function?
>> 
>> 
>> 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.

Yes, indeed.  This problem isn't specific to web requests, of course.
It applies to pretty much any socket-driven or GUI (event-driven)
library.  (For example, the (ossau gds-client) module in my
guile-debugging package.)

It would be nice to have a SRFI which standardised the way of
specifying handler procedures for such events, and of determining when
each such event source had work to process, along with standard
procedures for doing blocking and non-blocking selects on all the
events, and so on.

> 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.

These are all nice, but I don't see how they help with what I thought
you were saying was your problem, namely the taking control.  All of
these still need to be scheduled in some way.

> 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
> block!

Yes, and blocking is the problem.  The application usually needs to
know when it can call this without blocking.

> 	(define first (car lazy-results)) ; might need "force"
>
> 	; Handle the request (and to loop here)
> 	(my-handle-request first)
>
> 	(set! lazy-results (cdr lazy-results)) ; never blocks!
> 	(set! first (car lazy-results)) ; might need "force"
>
> 	; Loop back to my-handle-request (till '() )
>
> Or,
> 	; Could/will block, waiting for each mod-lisp request
> 	(for-each my-handle-request lazy-results)

That's a nice result, but I'd prefer a more general API able to
multiple different sources of input, as described above.

>>>* Do you want to see a SRFI that provides _just_ the mod_lisp
>>>protocol?
>> 
>> 
>> 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.

I see.  So combining my thoughts and yours, I think this would have
three levels to it.

- Generic API for specifying sources of input and how to handle them.

- The particular case of this API for an HTTP request handler.

- Your ideas for presenting the HTTP content in various useful ways.

Sorry that this mail is a bit random - I'm just thinking out loud
really, which isn't that constructive.  (And I also need to read your
code again in more detail, now I understand the architecture.)  I hope
it's of some interest though.

      Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-09-19 21:32     ` Neil Jerram
@ 2005-09-20  3:24       ` Alan Grover
  2005-09-20  4:44         ` Threads (was: mod_lisp for guile) Tomas Zerolo
  2005-12-04 10:07         ` mod_lisp for guile Neil Jerram
  0 siblings, 2 replies; 12+ messages in thread
From: Alan Grover @ 2005-09-20  3:24 UTC (permalink / raw)


Neil Jerram wrote:
(much elision)
> It seems to me, though, that there is nothing especially lispy about
> the module (mod_lisp) which runs inside Apache.  Presumably the Apache
> side of the protocol could be implemented in any language, or could be
> provided "native" by Apache itself?

It's in C. Nothing lispy here. It could be native, but, since it is not
essential to an HTTP server, it is left as a module.

> Is the form of the protocol itself lispy?  (I.e. parenthesised and
> readable using read.)

The protocol is not lispy. It sends each header as:
	header-name <new-line>
	header-value <new-line>
with an "end" as the last header-value.

Several "daemon-side" implementations have been written in other
languages. I think it is only called mod_lisp because it was originally
written for use with Common Lisp.

> How would using threads reduce resource usage?  Otherwise this all
> makes sense.

A thread doesn't require an entire process (like a fork does), in
particular, memory is shared. I think you could limit a thread's
resource requirements to just an execution "thread" (PC, registers,
stack), otherwise sharing everything within the one process. Being
light-weight/cheap is one of the major motivations for threads.

Though I read something recently that claimed some thread
(mis-)implementations are more costly than a fork, and often more costly
than you'd hope. Apparently, the Linux 2.6 thread implementation is in
user-space, which means it isn't very thrifty (and causes some other
interesting issues).

> So you mean that if someone has already written an HTTP request
> handler procedure for use with www-guile, it ought to be possible to
> reuse exactly that same procedure with your mod-lisp also?  Sounds
> good to me.

Also, I don't want to rewrite all the logic from that module (e.g.
query-parsing, etc. etc.).

My goal is to allow no change between CGI and mod_lisp (for certain www
library modules). Perl's CGI module transparently works under CGI or
mod_perl (an embedded Perl interpreter in the Apache process).


>>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.
> 
> 
> Yes, indeed.  This problem isn't specific to web requests, of course.
> It applies to pretty much any socket-driven or GUI (event-driven)
> library.  (For example, the (ossau gds-client) module in my
> guile-debugging package.)
> 
> It would be nice to have a SRFI which standardised the way of
> specifying handler procedures for such events, and of determining when
> each such event source had work to process, along with standard
> procedures for doing blocking and non-blocking selects on all the
> events, and so on.

I look forward to your work on the issue. :) I kind of like the
lazy-list solution, but I've been infected by a pure-and-lazy
programming language (Clean). I think some people call them generators.

I'm liking the lazy-list idea more and more. It seems to work well with
the tcp-socket listener pattern.

The old way:
	; off in somebodies library module
	; It "takes over"
	(define (daemon-loop handler)
	set-up listener
	Repeat forever:	
		block on accept
		spawn thread with accepted socket and handler
	)

	; In your code
	(define (my-handler ...)
		; called in a new-thread
		do-something)
	; we will now loop forever on accept/spawn
	(daemon-loop my-handler)

With a lazy-list, it would be something like
	; In your code
	(define mod_lisp-request
		(make-lazy-mod-lisp with-appropriate-tcp-code))
	; Whatever "daemon-loop" you want:
	(for-each
		spawn-my-thread
		mod_lisp-request)

>>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
>>block!
>>	(define first (car lazy-results)) ; might need "force"
> 
> Yes, and blocking is the problem.  The application usually needs to
> know when it can call this without blocking.

An interesting problem given the apparent PThreads implementations (any
blocking-call blocks all threads). In my prototype code, I "soft" block
(just block the one thread), using 'select.

In this case, it is probably OK (and expected) that the 'car would
"soft" block (until the next request comes in), since this is the
daemon-loop. You could push this loop into its own thread, and leave
your "main" thread unblocked.

Under PThreads, I am lead to believe that each "read", if it blocks,
blocks the entire process (all threads). But, under reasonable
circumstances, the blocking should be very short. However, if the Apache
side of mod_lisp is slow in writing, it would cause problems.

> I see.  So combining my thoughts and yours, I think this would have
> three levels to it.
> 
> - Generic API for specifying sources of input and how to handle them.

Well, I'm only addressing mod_lisp at the moment. Though I intend to let
the user (programmer) supply the socket-listener (or whatever they want
that results in a read/write port that appears to talk mod_lisp).

I'd be happy to work with you to extract the (to be written) lazy-list
stuff for general use.

You might want to look at Perl's Net modules. They are layered something
like you suggest: a generic TCP layer, a generic header-value/body
protocol, specific protocols like HTTP or SMTP.

> - The particular case of this API for an HTTP request handler.
> 
> - Your ideas for presenting the HTTP content in various useful ways.

I have plans for several more layers for web-applications. E.g. a
web-application skeleton (get request, decode request, change state,
decide on html, construct html), and layers of policy to fill it with
(e.g. a particular html-template system).

Though I've heard about continuation-passing web-frameworks, I'm not
currently working on them. Also, since I use Guile, there is the problem
that you can't use a continuation in a different thread.

> I hope
> it's of some interest though.

I have been interested. And, I thank you for taking the time.

-- Alan Grover


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Threads (was: mod_lisp for guile)
  2005-09-20  3:24       ` Alan Grover
@ 2005-09-20  4:44         ` Tomas Zerolo
  2005-09-20 12:12           ` Threads Alan Grover
  2005-12-04 10:07         ` mod_lisp for guile Neil Jerram
  1 sibling, 1 reply; 12+ messages in thread
From: Tomas Zerolo @ 2005-09-20  4:44 UTC (permalink / raw)
  Cc: guile-user


[-- Attachment #1.1: Type: text/plain, Size: 1253 bytes --]

On Mon, Sep 19, 2005 at 11:24:34PM -0400, Alan Grover wrote:
> Neil Jerram wrote:
> (much elision)
[...]
> > How would using threads reduce resource usage?  Otherwise this all
> > makes sense.

AFAIU inter-thread communication is just easier. And forking a thread
might be easier on VM than forking a process. On some bad process
implementations much more so.

> A thread doesn't require an entire process (like a fork does), in
> particular, memory is shared. I think you could limit a thread's
> resource requirements to just an execution "thread" (PC, registers,
> stack), otherwise sharing everything within the one process. Being
> light-weight/cheap is one of the major motivations for threads.
> 
> Though I read something recently that claimed some thread
> (mis-)implementations are more costly than a fork, and often more costly
> than you'd hope. Apparently, the Linux 2.6 thread implementation is in
> user-space, which means it isn't very thrifty (and causes some other
> interesting issues).

On Linux 2.6 and with glibc 2.0 you have native Posix threads, and a
quite spiffy implementation at that. See e.g.

  <http://kerneltrap.org/node/422>

Newer Guiles try to take advantage of that.

Regards
-- tomas

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 140 bytes --]

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Threads
  2005-09-20  4:44         ` Threads (was: mod_lisp for guile) Tomas Zerolo
@ 2005-09-20 12:12           ` Alan Grover
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Grover @ 2005-09-20 12:12 UTC (permalink / raw)


Tomas Zerolo wrote:
> On Mon, Sep 19, 2005 at 11:24:34PM -0400, Alan Grover wrote:
>>Though I read something recently that claimed some thread
>>(mis-)implementations are more costly than a fork, and often more costly
>>than you'd hope. Apparently, the Linux 2.6 thread implementation is in
>>user-space, which means it isn't very thrifty (and causes some other
>>interesting issues).
> 
> 
> On Linux 2.6 and with glibc 2.0 you have native Posix threads, and a
> quite spiffy implementation at that. See e.g.
> 
>   <http://kerneltrap.org/node/422>
> 
> Newer Guiles try to take advantage of that.

Thanks for the clarification. I should have been more careful and said
that Guile 1.6 apparently uses the (use space) pthreads library. Of
course, it is not clear to me how you figure out what is in your kernel
and/or glibc, nor what Guile might be using.

-- Alan Grover


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-09-20  3:24       ` Alan Grover
  2005-09-20  4:44         ` Threads (was: mod_lisp for guile) Tomas Zerolo
@ 2005-12-04 10:07         ` Neil Jerram
  2005-12-05 17:21           ` Alan Grover
  1 sibling, 1 reply; 12+ messages in thread
From: Neil Jerram @ 2005-12-04 10:07 UTC (permalink / raw)
  Cc: guile-user

Alan Grover <awgrover@mail.msen.com> writes:

> I look forward to your work on the issue. :) I kind of like the
> lazy-list solution, but I've been infected by a pure-and-lazy
> programming language (Clean). I think some people call them generators.
>
> I'm liking the lazy-list idea more and more. It seems to work well with
> the tcp-socket listener pattern.

Hi Alan,

I'm just picking up my interest in this again, and I can't see why you
think the lazy list approach will be practical.  For two reasons:

1. If you are going to reuse the Apache socket (i.e. Keep-Socket: 1),
   you need to read, sooner or later, all the available data for the
   current request, so you might as well read it all upfront and then
   present it to the caller as an alist.

2. Even if you're not reusing the Apache socket, you don't know where
   a given header will be in the stream.  So the chances are your
   caller will have to read most of the available data anyway in order
   to find the headers that it is interested again.  So again, might
   as well read the whole lot upfront and provide a more convenient
   interface.

Have I missed something or misunderstood you?

Regards,
        Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-12-04 10:07         ` mod_lisp for guile Neil Jerram
@ 2005-12-05 17:21           ` Alan Grover
  2005-12-15 23:21             ` Neil Jerram
  0 siblings, 1 reply; 12+ messages in thread
From: Alan Grover @ 2005-12-05 17:21 UTC (permalink / raw)
  Cc: guile-user

Neil Jerram wrote:

>> Hi Alan,
>>
>> I'm just picking up my interest in this again, and I can't see why you
>> think the lazy list approach will be practical.  For two reasons:
>>
>> 1. If you are going to reuse the Apache socket (i.e. Keep-Socket: 1),
>>    you need to read, sooner or later, all the available data for the
>>    current request, so you might as well read it all upfront and then
>>    present it to the caller as an alist.


Re-use of the socket seems to have several issues. I've deferred
thinking too much about it (and thus, haven't checked exactly how it
works), but have noted the following:

It seems to serialize http transactions. You have to complete the entire
request/response before handling the next one. Which is not so good if
you want to handle simultaneous requests. This is a generalization of
the problem you noted, since you have to respond before the next request
can even be seen.

As I develop my mod_lisp related code, I'll note the
trade-offs/implications of Keep-Socket. But, don't hold your breath for
the next release.


>> 2. Even if you're not reusing the Apache socket, you don't know where
>>    a given header will be in the stream.  So the chances are your
>>    caller will have to read most of the available data anyway in order
>>    to find the headers that it is interested again.  So again, might
>>    as well read the whole lot upfront and provide a more convenient
>>    interface.
>>
>> Have I missed something or misunderstood you?


Actually, your comments are interesting, since you assumed I meant a
lazy-list at the per-header level. Hmmm. Weird. Even intriguing: why
read the rest of the request if you get to a header that you tells you
to give up?

But, to address the question. Yes, there's a slight misunderstanding.

I meant for the granularity to be at the "request" level. So, it is a
(lazy) list of requests. I had conceived of the implementation
reading/parsing the entire request.

The lazy-ness is really in taking advantage of patterns for list
processing. Perhaps I didn't give an example like:
	(define list-of-http-transactions (mod_lisp some-port-listener))
	(for-each handle-request list-of-http-transactions)

As I looked at doing a lazy-list implementation, I was blocked by the
fact that I can't do the example I just gave. The standard (and library)
functions aren't generic for delay'd values. Thus, if I created a
lazy-list, I couldn't use it with libraries (even the basic for-each/map
functions) and neither could client code. By providing a lazy-list, I
would force client-code to use a separate library of lazy-list functions.

-- Alan Grover awgrover@mail.msen.com +1.734.476.0969


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-12-05 17:21           ` Alan Grover
@ 2005-12-15 23:21             ` Neil Jerram
  2005-12-16 13:21               ` Alan Grover
  0 siblings, 1 reply; 12+ messages in thread
From: Neil Jerram @ 2005-12-15 23:21 UTC (permalink / raw)
  Cc: guile-user

Alan Grover <awgrover@mail.msen.com> writes:

> Actually, your comments are interesting, since you assumed I meant a
> lazy-list at the per-header level.

Yes.

> Hmmm. Weird. Even intriguing: why read the rest of the request if
> you get to a header that you tells you to give up?

That's not a mainline case, though, so not very compelling.

> But, to address the question. Yes, there's a slight misunderstanding.
>
> I meant for the granularity to be at the "request" level. So, it is a
> (lazy) list of requests. I had conceived of the implementation
> reading/parsing the entire request.

Yes, I see that now.

> The lazy-ness is really in taking advantage of patterns for list
> processing. Perhaps I didn't give an example like:
> 	(define list-of-http-transactions (mod_lisp some-port-listener))
> 	(for-each handle-request list-of-http-transactions)

That's kind of neat, but doesn't actually feel very natural to me.
When I have socket input to deal with, I typically want (or rather
need) to select on the socket along with other stuff, and then
dispatch the next request when select indicates data available.  I
don't see how that could naturally be rewritten in terms of list
operations, or that it would be helpful to do so.

> As I looked at doing a lazy-list implementation, I was blocked by the
> fact that I can't do the example I just gave. The standard (and library)
> functions aren't generic for delay'd values. Thus, if I created a
> lazy-list, I couldn't use it with libraries (even the basic for-each/map
> functions) and neither could client code. By providing a lazy-list, I
> would force client-code to use a separate library of lazy-list functions.

Yes, indeed.  Guile does come with a lazy list library, though - have
you seen (ice-9 streams)?

Regards,
        Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-12-15 23:21             ` Neil Jerram
@ 2005-12-16 13:21               ` Alan Grover
  2005-12-29 10:18                 ` Neil Jerram
  0 siblings, 1 reply; 12+ messages in thread
From: Alan Grover @ 2005-12-16 13:21 UTC (permalink / raw)
  Cc: guile-user

Neil Jerram wrote:
> Alan Grover <awgrover@mail.msen.com> writes:
>>The lazy-ness is really in taking advantage of patterns for list
>>processing. Perhaps I didn't give an example like:
>>	(define list-of-http-transactions (mod_lisp some-port-listener))
>>	(for-each handle-request list-of-http-transactions)
> 
> 
> That's kind of neat, but doesn't actually feel very natural to me.
> When I have socket input to deal with, I typically want (or rather
> need) to select on the socket along with other stuff, and then
> dispatch the next request when select indicates data available.  I
> don't see how that could naturally be rewritten in terms of list
> operations, or that it would be helpful to do so.

Could you talk a little bit more about the "select with other stuff"
pattern? What kind of stuff?

> Yes, indeed.  Guile does come with a lazy list library, though - have
> you seen (ice-9 streams)?

I don't think I've looked at it yet.


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: mod_lisp for guile
  2005-12-16 13:21               ` Alan Grover
@ 2005-12-29 10:18                 ` Neil Jerram
  0 siblings, 0 replies; 12+ messages in thread
From: Neil Jerram @ 2005-12-29 10:18 UTC (permalink / raw)
  Cc: guile-user

Alan Grover <awgrover@mail.msen.com> writes:

> Could you talk a little bit more about the "select with other stuff"
> pattern? What kind of stuff?

Yes, here are two examples.

1. In gds-server.scm in guile-debugging, I have a process that needs
   to accept both TCP connections from Guile client processes, and
   protocol instructions on its standard input from Emacs.  So I
   manage all this by selecting on (i) standard input, (ii) the TCP
   server socket, (iii) all the TCP connection sockets.

2. In another project X, I have an instance of X which acts as a
   central management point for several other instances of X, and
   which can itself be controlled through a web interface.  The
   central X handles all its possible inputs by selecting on both the
   web server socket and the sockets to the other Xs.

Do these help?  Please let me know if they're not clear enough.

I might be able to avoid these selects by using threads, but I've
acquired a preference for doing things this way.  In my experience
threads are more difficult to debug, and their implementation across
platforms is patchy.

Regards,
        Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-12-29 10:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-15 17:25 mod_lisp for guile Alan Grover
2005-09-16 18:46 ` Neil Jerram
2005-09-19 14:46   ` Alan Grover
2005-09-19 21:32     ` Neil Jerram
2005-09-20  3:24       ` Alan Grover
2005-09-20  4:44         ` Threads (was: mod_lisp for guile) Tomas Zerolo
2005-09-20 12:12           ` Threads Alan Grover
2005-12-04 10:07         ` mod_lisp for guile Neil Jerram
2005-12-05 17:21           ` Alan Grover
2005-12-15 23:21             ` Neil Jerram
2005-12-16 13:21               ` Alan Grover
2005-12-29 10:18                 ` Neil Jerram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).