Update domain name to kpe.io
[cl-modlisp.git] / doc / readme.lml
index f534b2501335074c391a20c01de61a855ee904d8..d09541c32729e330b4993df0a84be81cc05da153 100644 (file)
@@ -2,7 +2,7 @@
 
 (in-package #:lml2)
 
-(page ("readme")
+(html-file-page ("readme")
   (html      
    (:head
     (:title "cl-modlisp readme")
      ((:a :href "http://www.fractalconcept.com") "http://www.fractalconcept.com")
      ").")
     (:h2 "Features")
-    (ul
-     (li "support of 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 "
+    (:ul
+     (: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 "Demonstration processor included"))
+     (:li "Optional timeout of worker processes")
+     (:li "Two process models for flexibility")
+     (:li "Demonstration processor included"))
     (:h2 "Prerequisites")
-    (ul
-     (li "Apache 1.3.x")
-     (li "mod_lisp apache module ("
+    (:ul
+     (:li "Apache 1.3.x")
+     (:li "mod_lisp apache module ("
         ((:a :href "http://www.fractalconcept.com")
           "http://www.fractalconcept.com")
         ").")
-     (li "kmrcl library ("
-        ((:a :href "http://files.b9.com/kmrcl")
-          "http://files.b9.com/kmrcl")
+     (:li "kmrcl library ("
+        ((:a :href "http://files.kpe.io/kmrcl")
+          "http://files.kpe.io/kmrcl")
         ").")
-     (li "asdf ("
+     (:li "asdf ("
         ((:a :href "http://www.sf.net/projects/cclan")
           "http://www.sf.net/projects/cclan")
         ")."))
 
     (:h2 "Supported Platforms")
-    (ul
-     (li "Allegro v6.2")
-     (li "CMUCL 18e")
-     (li "Lispworks v4.2")
-     (li "SBCL 0.8.1 with sb-thread (multi-threading)"))
+    (:ul
+     (:li "Allegro v6.2")
+     (:li "CMUCL 18e")
+     (:li "Lispworks v4.2")
+     (:li "SBCL 0.8.1 with sb-thread (multi-threading)"))
 
     (: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:")
-     
-   apt-get install libapache-mod-lisp cl-modlisp cl-kmrcl
-
-If you are not using Debian, you will need to download and install
-mod_lisp, cl-modlisp, and cl-kmrcl manually.
-
-2. Add something like the below to httpd.conf and then restart apache
-      LispServer 127.0.0.1 20123 "localhost"
-      AddHandler lisp-handler .lsp
-
-3. Start your Lisp implementation and load cl-modlisp with 
-   (asdf:operate 'asdf:load-op 'modlisp) 
-
-4. Start the server with 
-      (ml:modlisp-start :port 20123))
-
-5. Try some demostration pages
-      lynx http://localhost/fixed.lsp
-      lynx http://localhost/debug.lsp
-
-6. Shutdown the all cl-modlisp servers with
-     (ml:modlisp-stop-all)
-
-
-USAGE
------
-
-Return to the demo.lisp file for some examples of using cl-modlisp.
+    (: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:"
+     (: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"
+      (: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"
+      (:div (:tt "(asdf:operate 'asdf:load-op 'modlisp)")))
+     (:li
+      "Start the server with"
+      (:div (:tt "(ml:modlisp-start :port 20123)")))
+     (:li "Try some demostration pages"
+         (:div (:tt "links http://localhost/fixed.lsp"))
+         (:div (:tt "links http://localhost/debug.lsp")))
+     (:li "Shutdown the all cl-modlisp servers with"
+         (: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 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/")
+)))))