X-Git-Url: http://git.kpe.io/?p=cl-modlisp.git;a=blobdiff_plain;f=doc%2Freadme.lml;h=d09541c32729e330b4993df0a84be81cc05da153;hp=8a54a53bbb036fe8f7ae9947276d07bc4f1c2e32;hb=HEAD;hpb=3cd1fc37754064befbc4e5e9050ed8849da3ce09 diff --git a/doc/readme.lml b/doc/readme.lml index 8a54a53..d09541c 100644 --- a/doc/readme.lml +++ b/doc/readme.lml @@ -21,12 +21,14 @@ ").") (:h2 "Features") (:ul - (:li "support of AllegroCL, CMUCL, SBCL with sb-thread, and Lispworks.") + (:li "support for AllegroCL, CMUCL, SBCL with sb-thread, and Lispworks.") (:li "listener and worker socket/process management so that shutting down the listener closes all related open sockets and terminates all related proceses.") (:li "support for running multiple command processors on multiple ports.") (:li "transparent support for precomputing the HTML or XML response to take advantage of HTTP/1.1's Keep-Alive feature. This is switchable with a single keyword argument to the macro " (:tt "with-ml-page") ".") + (:li "Optional timeout of worker processes") + (:li "Two process models for flexibility") (:li "Demonstration processor included")) (:h2 "Prerequisites") (:ul @@ -36,8 +38,8 @@ "http://www.fractalconcept.com") ").") (:li "kmrcl library (" - ((:a :href "http://files.b9.com/kmrcl") - "http://files.b9.com/kmrcl") + ((:a :href "http://files.kpe.io/kmrcl") + "http://files.kpe.io/kmrcl") ").") (:li "asdf (" ((:a :href "http://www.sf.net/projects/cclan") @@ -54,38 +56,109 @@ (:h2 "Quickstart") (:ul (:li "The easiest way to install is to use the Debian GNU/Linux operating system. Using the testing or unstable distributions, you can give the command:" - (:p - "apt-get install libapache-mod-lisp cl-modlisp cl-kmrcl") - (:p + (:div + (:tt "apt-get install libapache-mod-lisp cl-modlisp cl-kmrcl")) + (:div "If you are not using Debian, you will need to download and install mod_lisp, cl-modlisp, and cl-kmrcl manually.")) (:li "Add something like the below to httpd.conf and then restart apache" - (:br) - "LispServer 127.0.0.1 20123 \"localhost\"" - (:br) - "AddHandler lisp-handler .lsp") + (:div (:tt "LispServer 127.0.0.1 20123 \"localhost\"")) + (:div (:tt "AddHandler lisp-handler .lsp"))) (:li "Start your Lisp implementation and load cl-modlisp with" - (:br) - "(asdf:operate 'asdf:load-op 'modlisp)") + (:div (:tt "(asdf:operate 'asdf:load-op 'modlisp)"))) (:li "Start the server with" - (:br) - "(ml:modlisp-start :port 20123)") + (:div (:tt "(ml:modlisp-start :port 20123)"))) (:li "Try some demostration pages" - (:br) - "links http://localhost/fixed.lsp" - (:br) - "links http://localhost/debug.lsp") + (:div (:tt "links http://localhost/fixed.lsp")) + (:div (:tt "links http://localhost/debug.lsp"))) (:li "Shutdown the all cl-modlisp servers with" - (:br) - "(ml:modlisp-stop-all)")) + (:div (:tt "(ml:modlisp-stop-all)")))) + (:h2 "Process Models") + (:p "There are two process models") + (:ul + (:li (:div (:b "Each connection spawns a new thread")) + (:div "This is the default model. Each new connection to listener socket spawns a new connection. This allows for an arbitrary number of concurrent connections. This has advantages if the workers require a long execution time.")) + (:li (:div (:b "Fixed pool of workers")) + (:div "This model is selected by passing the number of worker processes to " + (:tt "init/listener") + " with the keyword " + (:tt "number-fixed-workers") + ". This model has a lower overhead since new processes are not created and destroyed with each connection. It has advantages when the workers have a short execution time."))) + (:h2 "Usage") - (:p "The demo.lisp file for some examples of using cl-modlisp.") - ))) + (:p "The demo.lisp file for examples of using cl-modlisp.") + ) + + (:ul) + (:li (:div (:strong "Overview")) + (:div "cl-modlisp is a multi-threaded handler for HTTP requests forwarded by Marc Battyani's (http://www.fractalconcept.com) mod_lisp Apache module.")) + (:li (:div (:strong "Design Goals")) + (:div "cl-modlisp is designed as a thin layer to dispatch a mod_lisp request with multi-platform compatibility. Currently, cl-modlisp supports SBCL [multithreaded], CMUCL, AllegroCL, and Lispworks.")) + (:li (:div (:strong "Dispatch model")) + (:div "Extremely simple: All requests are forwarded to a single processor that is passed as a parameter to cl-modlisp's start-up function.")) + (:li (:div (:strong "Configuration")) + (:div "All configuration is set by passing keyword arguments to +modlisp-start") + (:ul + (:li "port number - a number") + (:li "processor - function designator which will receive all requests") + (:li "processor-args - list of extra arguments to be passed to processor") + (:li "timeout - NIL means never timeout otherwise number of seconds") + (:li "catch-errors - non-NIL means to catch errors") + (:li "number-fixed-workers - NIL means to spawn a new worker process for each request") + (:li "remote-host-checker - optional function designator to check the remote host IP address. Used for filtering requests."))) + (:li (:div (:strong "Processor function")) + (:div +"This function receives an argument of the 'command' alist and any +other arguments passed to modlisp-start as the :processor-args. The +'command' alist is an associative list of keys and values received +from modlisp. No preprocessing is done except that keys are converted +from strings to keywords forced to the default implementation case.")) + (:li (:div (:strong "Default Processor")) + (:div "The default processor is a simple demo command processor not intended for end-user.")) + (:li (:div "URI Processing") + (:div "None. The raw URL is the value of the :url key in the command alist.")) + (:li (:div "Responses") + (:div "Responses are written to modlisp:*modlisp-socket*. The raw HTTP/1.1 header needs to be generated by the application.")) + (:li (:div "Utility functions") + (:div "A few utility functions are provided") + (:ul + (:li (:div "with-ml-page") + (:div "Outputs the body of the macro along with the HTTP/1.1 headers. Supports both precomputing responses with keep-alive connections and also outputing response to socket as it is generated. The latter is useful for lengthye reponses in time or length. Also support setting the content-type (default \"text/html\") and arbitrary list of headers.")) + (:li (:div "query-to-alist") + (:div "Converts posted query to an alist. Doesn't handle multipart forms.")) + (:li (:div "redirect-to-location")))) + (:li (:div (:strong "Known issues")) + (:ul + (:li "This application has been most tested on AllegroCL.") + (:li +(:p "By design, is not practical an application platform. It is should have +an API package wrapped around this library which supports useful +features like processing URIs, dispatches, cookies, and querys [URI +and single/multipart POSTs]") +(:p +"Rather than adding these features to cl-modlisp, I've been working on +a library which uses a session-id and dispatch model based on Franz's +webactions library. It also integrates my portable version of Franz's +URI module and adds query processing similar on AllegroServer's +request-query functions. This library can used with both cl-modlisp +and AllegroServe as connectors. However, as this library has grown, it +looks more and more like AllegroServe, I've begun to question the +value of using this library compared to just using Portable +AllegroServe with just my webactions-like session-id and dispatch +processors. In my mind, the greatest advantage of using this library +is that it is a much smaller task maintaining cross-implementation +compatibility with the cl-modlisp connector version maintaining such +compatibility with paserve. The disadvantage of this library is that I +dislike cloning AllegroServe's query and cookie processing. I do so, +though, because I think their API is quite reasonable. This library +is currently driving http://umlisp.kpe.io/") +)))))