#!/usr/bin/python
import sys, os, getopt, threading, time
-import ashd.proto, ashd.util
+import ashd.proto, ashd.util, ashd.perf
+try:
+ import pdm.srv
+except:
+ pdm = None
def usage(out):
- out.write("usage: ashd-wsgi [-hA] [-p MODPATH] [-l REQLIMIT] HANDLER-MODULE [ARGS...]\n")
+ out.write("usage: ashd-wsgi [-hA] [-m PDM-SPEC] [-p MODPATH] [-l REQLIMIT] HANDLER-MODULE [ARGS...]\n")
reqlimit = 0
modwsgi_compat = False
-opts, args = getopt.getopt(sys.argv[1:], "+hAp:l:")
+opts, args = getopt.getopt(sys.argv[1:], "+hAp:l:m:")
for o, a in opts:
if o == "-h":
usage(sys.stdout)
modwsgi_compat = True
elif o == "-l":
reqlimit = int(a)
+ elif o == "-m":
+ if pdm is not None:
+ pdm.srv.listen(a)
if len(args) < 1:
usage(sys.stderr)
sys.exit(1)
resp[:] = status, headers
return write
- respiter = handler(env, startreq)
+ reqevent = ashd.perf.request(env)
+ exc = (None, None, None)
try:
+ respiter = handler(env, startreq)
try:
- for data in respiter:
- write(data)
- if resp:
- flushreq()
- except closed:
- pass
+ try:
+ for data in respiter:
+ write(data)
+ if resp:
+ flushreq()
+ except closed:
+ pass
+ finally:
+ if hasattr(respiter, "close"):
+ respiter.close()
+ if resp:
+ reqevent.response(resp)
+ except:
+ exc = sys.exc_info()
finally:
- if hasattr(respiter, "close"):
- respiter.close()
+ reqevent.__exit__(*exc)
flightlock = threading.Condition()
inflight = 0
--- /dev/null
+try:
+ import pdm.perf
+except:
+ pdm = None
+
+reqstat = {}
+
+if pdm:
+ statistics = pdm.perf.staticdir()
+ statistics["req"] = pdm.perf.valueattr(reqstat)
+ requests = pdm.perf.eventobj()
+
+ class reqstart(pdm.perf.startevent):
+ def __init__(self, env):
+ super(reqstart, self).__init__()
+ self.method = env.get("REQUEST_METHOD")
+ self.uri = env.get("REQUEST_URI")
+ self.host = env.get("HTTP_HOST")
+
+ class reqfinish(pdm.perf.finishevent):
+ def __init__(self, start, aborted, status):
+ super(reqfinish, self).__init__(start, aborted)
+ self.status = status
+
+class request(object):
+ def __init__(self, env):
+ self.resp = None
+ if pdm:
+ self.startev = reqstart(env)
+ requests.notify(self.startev)
+
+ def response(self, resp):
+ self.resp = resp
+
+ def finish(self, aborted):
+ key = None
+ status = None
+ try:
+ if len(self.resp) > 0:
+ status = self.resp[0]
+ p = status.find(" ")
+ if p < 0:
+ key = status
+ else:
+ key = status[:p]
+ except:
+ pass
+ reqstat[key] = reqstat.setdefault(key, 0) + 1
+ if pdm:
+ requests.notify(reqfinish(self.startev, aborted, status))
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *excinfo):
+ self.finish(bool(excinfo[0]))
+ return False
SYNOPSIS
--------
-*ashd-wsgi* [*-hA*] [*-p* 'MODPATH'] [*-l* 'LIMIT'] 'HANDLER-MODULE' ['ARGS'...]
+*ashd-wsgi* [*-hA*] [*-m* 'PDM-SPEC'] [*-p* 'MODPATH'] [*-l* 'LIMIT'] 'HANDLER-MODULE' ['ARGS'...]
DESCRIPTION
-----------
complete; if none does, *ashd-wsgi* will assume that the
process is foobar and *abort*(3).
+*-m* 'PDM-SPEC'::
+
+ If the PDM library is installed on the system, create a
+ listening socket for connection PDM clients according to
+ 'PDM-SPEC'.
+
PROTOCOL
--------
#!/usr/bin/python3
import sys, os, getopt, threading, time, locale, collections
-import ashd.proto, ashd.util
+import ashd.proto, ashd.util, ashd.perf
+try:
+ import pdm.srv
+except:
+ pdm = None
def usage(out):
- out.write("usage: ashd-wsgi3 [-hA] [-p MODPATH] [-l REQLIMIT] HANDLER-MODULE [ARGS...]\n")
+ out.write("usage: ashd-wsgi3 [-hA] [-m PDM-SPEC] [-p MODPATH] [-l REQLIMIT] HANDLER-MODULE [ARGS...]\n")
reqlimit = 0
modwsgi_compat = False
-opts, args = getopt.getopt(sys.argv[1:], "+hAp:l:")
+opts, args = getopt.getopt(sys.argv[1:], "+hAp:l:m:")
for o, a in opts:
if o == "-h":
usage(sys.stdout)
modwsgi_compat = True
elif o == "-l":
reqlimit = int(a)
+ elif o == "-m":
+ if pdm is not None:
+ pdm.srv.listen(a)
if len(args) < 1:
usage(sys.stderr)
sys.exit(1)
resp[:] = status, headers
return write
- respiter = handler(env, startreq)
- try:
+ with ashd.perf.request(env) as reqevent:
+ respiter = handler(env, startreq)
try:
- for data in respiter:
- write(data)
- if resp:
- flushreq()
- except closed:
- pass
- finally:
- if hasattr(respiter, "close"):
- respiter.close()
+ try:
+ for data in respiter:
+ write(data)
+ if resp:
+ flushreq()
+ except closed:
+ pass
+ finally:
+ if hasattr(respiter, "close"):
+ respiter.close()
+ if resp:
+ reqevent.response(resp)
flightlock = threading.Condition()
inflight = 0
--- /dev/null
+import collections
+try:
+ import pdm.perf
+except:
+ pdm = None
+
+reqstat = {}
+
+if pdm:
+ statistics = pdm.perf.staticdir()
+ statistics["req"] = pdm.perf.valueattr(reqstat)
+ requests = pdm.perf.eventobj()
+
+ class reqstart(pdm.perf.startevent):
+ def __init__(self, env):
+ super(reqstart, self).__init__()
+ self.method = env.get("REQUEST_METHOD")
+ self.uri = env.get("REQUEST_URI")
+ self.host = env.get("HTTP_HOST")
+
+ class reqfinish(pdm.perf.finishevent):
+ def __init__(self, start, aborted, status):
+ super(reqfinish, self).__init__(start, aborted)
+ self.status = status
+
+class request(object):
+ def __init__(self, env):
+ self.resp = None
+ if pdm:
+ self.startev = reqstart(env)
+ requests.notify(self.startev)
+
+ def response(self, resp):
+ self.resp = resp
+
+ def finish(self, aborted):
+ key = None
+ status = None
+ try:
+ if len(self.resp) > 0:
+ status = self.resp[0]
+ if isinstance(status, collections.ByteString):
+ status = status.decode("latin-1")
+ else:
+ status = str(status)
+ p = status.find(" ")
+ if p < 0:
+ key = status
+ else:
+ key = status[:p]
+ except:
+ pass
+ reqstat[key] = reqstat.setdefault(key, 0) + 1
+ if pdm:
+ requests.notify(reqfinish(self.startev, aborted, status))
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *excinfo):
+ self.finish(bool(excinfo[0]))
+ return False
SYNOPSIS
--------
-*ashd-wsgi3* [*-hA*] [*-p* 'MODPATH'] [*-l* 'LIMIT'] 'HANDLER-MODULE' ['ARGS'...]
+*ashd-wsgi3* [*-hA*] [*-m* 'PDM-SPEC'] [*-p* 'MODPATH'] [*-l* 'LIMIT'] 'HANDLER-MODULE' ['ARGS'...]
DESCRIPTION
-----------
complete; if none does, *ashd-wsgi3* will assume that the
process is foobar and *abort*(3).
+*-m* 'PDM-SPEC'::
+
+ If the PDM library is installed on the system, create a
+ listening socket for connection PDM clients according to
+ 'PDM-SPEC'.
+
PROTOCOL
--------