Commit | Line | Data |
---|---|---|
338bee9d FT |
1 | ashd-wsgi(1) |
2 | ============ | |
3 | ||
4 | NAME | |
5 | ---- | |
6 | ashd-wsgi - WSGI adapter for ashd(7) | |
7 | ||
8 | SYNOPSIS | |
9 | -------- | |
0690bcf6 | 10 | *ashd-wsgi* [*-hAL*] [*-m* 'PDM-SPEC'] [*-p* 'MODPATH'] [*-t* 'HANDLING-MODEL'] 'HANDLER-MODULE' ['ARGS'...] |
338bee9d FT |
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 | |
0690bcf6 FT |
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. | |
338bee9d FT |
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 | ||
0690bcf6 FT |
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 | ||
338bee9d FT |
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 | ||
0690bcf6 | 66 | *-t* 'HANDLING-MODEL':: |
3e11d7ed | 67 | |
0690bcf6 FT |
68 | Specify the way *ashd-wsgi* handles requests. See below, under |
69 | REQUEST HANDLING. | |
3e11d7ed | 70 | |
d5ee5cde FT |
71 | *-m* 'PDM-SPEC':: |
72 | ||
73 | If the PDM library is installed on the system, create a | |
e3aca55c | 74 | listening socket for connecting PDM clients according to |
d5ee5cde FT |
75 | 'PDM-SPEC'. |
76 | ||
338bee9d FT |
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 | |
0690bcf6 FT |
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. | |
338bee9d FT |
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 | ||
0690bcf6 FT |
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 | ||
338bee9d FT |
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 | |
0690bcf6 | 169 | xset python-handler chain |
338bee9d FT |
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/> |