1 import os, threading, time, logging
3 log = logging.getLogger("ashd.serve")
5 seqlk = threading.Lock()
14 class reqthread(threading.Thread):
15 def __init__(self, name=None):
17 name = "Request handler %i" % reqseq()
18 super().__init__(name=name)
27 log.error("exception occurred when handling request", exc_info=True)
29 class closed(IOError):
31 super().__init__("The client has closed the connection.")
33 class wsgithread(reqthread):
34 def __init__(self, **kwargs):
35 super().__init__(**kwargs)
42 def writehead(self, status, headers):
44 def writedata(self, data):
47 def write(self, data):
56 raise Exception("Cannot send response body before starting response.")
58 self.writehead(self.status, self.headers)
60 def startreq(self, status, headers, exc_info=None):
62 if exc_info: # Nice calling convetion ^^
67 exc_info = None # CPython GC bug?
69 raise Exception("Can only start responding once.")
71 self.headers = headers
76 respiter = self.handlewsgi()
83 if hasattr(respiter, "close"):
88 class calllimiter(object):
89 def __init__(self, limit):
91 self.lock = threading.Condition()
94 def waited(self, time):
96 raise RuntimeError("Waited too long")
101 while self.inflight >= self.limit:
103 self.waited(time.time() - start)
107 def __exit__(self, *excinfo):
113 def call(self, target):
117 class abortlimiter(calllimiter):
118 def waited(self, time):