ratequeue: Log request blocking.
[ashd.git] / python / doc / ashd-wsgi.doc
1 ashd-wsgi(1)
2 ============
3
4 NAME
5 ----
6 ashd-wsgi - WSGI adapter for ashd(7)
7
8 SYNOPSIS
9 --------
10 *ashd-wsgi* [*-hAL*] [*-m* 'PDM-SPEC'] [*-p* 'MODPATH'] [*-t* 'HANDLING-MODEL'] 'HANDLER-MODULE' ['ARGS'...]
11
12 DESCRIPTION
13 -----------
14
15 The *ashd-wsgi* handler translates *ashd*(7) requests to WSGI
16 requests, and passes them to a specified Python handler module. The
17 precise Python convention for doing so is described in the PROTOCOL
18 section, below.
19
20 *ashd-wsgi* is a persistent handler, as defined in *ashd*(7). It uses
21 multithreaded dispatching in a single Python interpreter, which means
22 that WSGI applications that use it need to be thread-safe, but that
23 they can also share all Python data structures and global variables
24 between requests. More precisely, *ashd-wsgi* implements a couple of
25 slightly different ways to handle requests and threads, which can be
26 configured using the *-t* option, as described in the REQUEST HANDLING
27 section, below.
28
29 The Python module that *ashd-wsgi* comes with also contains a standard
30 handler module, `ashd.wsgidir`, which serves individual WSGI
31 applications directly from the files in which they reside and as such
32 makes this program useful as a *dirplex*(1) handler. Please see its
33 Python documentation for further details.
34
35 *ashd-wsgi* requires the `ashd.proto` and `ashd.util` modules, which
36 are only available for CPython. If you want to use some other Python
37 implementation instead, you may want to use the *scgi-wsgi*(1) program
38 instead, along with *callscgi*(1).
39
40 OPTIONS
41 -------
42
43 *-h*::
44
45         Print a brief help message to standard output and exit.
46
47 *-A*::
48
49         Use the convention used by Apache's mod_wsgi module to find
50         the WSGI application object. See the PROTOCOL section, below,
51         for details.
52
53 *-L*::
54         By default, *ashd-wsgi* sets up the Python logging with a
55         logging format and for logging to standard error. The *-L*
56         option suppresses that behavior, so that any handler module
57         may set up logging itself.
58
59 *-p* 'MODPATH'::
60
61         Prepend 'MODPATH' to Python's `sys.path`; can be given multiple
62         times. Note that the working directory of *ashd-wsgi* is not
63         on Python's module path by default, so if you want to use a
64         module in that directory, you will need to specify "`-p .`".
65
66 *-t* 'HANDLING-MODEL'::
67
68         Specify the way *ashd-wsgi* handles requests. See below, under
69         REQUEST HANDLING.
70
71 *-m* 'PDM-SPEC'::
72
73         If the PDM library is installed on the system, create a
74         listening socket for connecting PDM clients according to
75         'PDM-SPEC'.
76
77 PROTOCOL
78 --------
79
80 When starting, *ashd-wsgi* will attempt to import the module named by
81 'HANDLER-MODULE', look for an object named `wmain` in that module,
82 call that object passing the 'ARGS' (as Python strings) as positional
83 parameters, and use the returned object as the WSGI application
84 object. If the *-A* option was specified, it will look for an object
85 named `application` instead of `wmain`, and use that object directly
86 as the WSGI application object.
87
88 When calling the WSGI application, a new thread is started for each
89 request, in which the WSGI application object is called (but see
90 below, under REQUEST HANDLING, for details). All requests run in the
91 same interpreter, so it is guaranteed that data structures and global
92 variables can be shared between requests.
93
94 The WSGI environment is the standard CGI environment, including the
95 `SCRIPT_FILENAME` variable whenever the `X-Ash-File` header was
96 included in the request.
97
98 REQUEST HANDLING
99 ----------------
100
101 *ashd-wsgi* can be configured to handle requests in various ways,
102 using the *-t* command-line option. The argument to the *-t* option
103 takes the form 'HANDLER'[*:*'PAR'[*=*'VAL'][(*,*'PAR'[*=*'VAL'])...]],
104 in order to specify the handler model, along with parameters to the
105 same (using the same syntax as the port specifications of
106 *htparser*(1)). The 'HANDLER' can be any of the following:
107
108 *free*[*:max=*'MAX-THREADS'*,timeout=*'TIMEOUT']::
109
110         The *free* handler, which is the default, starts a new thread
111         for every incoming request, which runs the whole request in
112         its entirety, from running the WSGI handler function to
113         sending the contents of the response iterator. Optionally,
114         'MAX-THREADS' may be specified to an integer, in which case no
115         more than that many request-handler threads will be allowed to
116         run at any one time (by default, any number of threads are
117         allowed to run, without limit). If further requests come in
118         while 'MAX-THREADS' handlers are running, the request dispatch
119         thread itself will block until one exits, making new requests
120         queue up in the socket over which they arrive, eventually
121         filling up its buffers if no threads exit, in turn making the
122         parent handler either block or receive *EAGAIN* errors. Also,
123         if 'MAX-THREADS' is specified, 'TIMEOUT' may also be
124         specified, to tell the dispatcher thread to never block more
125         than so many seconds for a handler thread to exit. If it is
126         forced to wait longer than 'TIMEOUT' seconds, it will assume
127         the whole process is somehow foobar and will *abort*(3).
128
129 *rplex*[*:max=*'MAX-THREADS']::
130
131         The *rplex* handler starts a new thread for every incoming
132         request, but unlike the *free* handler, only the WSGI handler
133         function runs in that thread. Whenever any such thread, then,
134         returns its response iterator, all such iterators will be
135         passed to a single independent thread which sends their
136         contents to the clients, multiplexing between them whenever
137         their respective clients are ready to receive data. Like the
138         *free* handler, a 'MAX-THREADS' argument may be given to
139         specify how many handler threads are allowed to run at the
140         same time. The main advantage, compared to the *free* handler,
141         is that the *rplex* handler allows an arbitrary number of
142         response iterators to run simultaneously without tying up
143         handler threads, therefore not counting towards 'MAX-THREADS',
144         which may be necessary for applications handling large
145         files. However, it must be noted that no response iterators in
146         the application may block on returning data, since that would
147         also block all other running responses. Also, the *rplex*
148         handler does not support the `write` function returned by
149         `start_request`, according to the WSGI specification.
150
151 *single*::
152
153         The *single* handler starts no threads at all, running all
154         received requests directly in the main dispatch thread. It is
155         probably not good for much except as the simplest possible
156         example of a request handling model.
157
158 EXAMPLES
159 --------
160
161 The following *dirplex*(1) configuration can be used for serving WSGI
162 modules directly from the filesystem.
163
164 --------
165 child wsgidir
166   exec ashd-wsgi ashd.wsgidir
167 match
168   filename *.wsgi
169   xset python-handler chain
170   handler wsgidir
171 --------
172
173 Since *ashd-wsgi* is a persistent handler, it can be used directly as
174 a root handler for *htparser*(1). For instance, if the directory
175 `/srv/www/foo` contains a `wsgi.py` file, which declares a standard
176 WSGI `application` object, it can be served with the following
177 command:
178
179 --------
180 htparser plain:port=8080 -- ashd-wsgi -Ap /srv/www/foo wsgi
181 --------
182
183 AUTHOR
184 ------
185 Fredrik Tolf <fredrik@dolda2000.com>
186
187 SEE ALSO
188 --------
189 *scgi-wsgi*(1), *ashd*(7), <http://wsgi.org/>