Revision 33bbdbec
b/lib/http.py | ||
---|---|---|
32 | 32 |
import signal |
33 | 33 |
import logging |
34 | 34 |
import errno |
35 |
import threading |
|
35 | 36 |
|
36 | 37 |
from cStringIO import StringIO |
37 | 38 |
|
... | ... | |
836 | 837 |
send_headers = self.DEFAULT_HEADERS.copy() |
837 | 838 |
|
838 | 839 |
if self.request.headers: |
839 |
send_headers.update(req.headers)
|
|
840 |
send_headers.update(self.request.headers)
|
|
840 | 841 |
|
841 | 842 |
send_headers[HTTP_HOST] = "%s:%s" % (self.request.host, self.request.port) |
842 | 843 |
|
... | ... | |
1302 | 1303 |
"Timeout while shutting down connection") |
1303 | 1304 |
|
1304 | 1305 |
|
1306 |
class _HttpClientPendingRequest(object): |
|
1307 |
"""Data class for pending requests. |
|
1308 |
|
|
1309 |
""" |
|
1310 |
def __init__(self, request): |
|
1311 |
self.request = request |
|
1312 |
|
|
1313 |
# Thread synchronization |
|
1314 |
self.done = threading.Event() |
|
1315 |
|
|
1316 |
|
|
1305 | 1317 |
class HttpClientWorker(workerpool.BaseWorker): |
1306 | 1318 |
"""HTTP client worker class. |
1307 | 1319 |
|
1308 | 1320 |
""" |
1309 |
def RunTask(self, req): |
|
1310 |
HttpClientRequestExecutor(req) |
|
1321 |
def RunTask(self, pend_req): |
|
1322 |
try: |
|
1323 |
HttpClientRequestExecutor(pend_req.request) |
|
1324 |
finally: |
|
1325 |
pend_req.done.set() |
|
1311 | 1326 |
|
1312 | 1327 |
|
1313 | 1328 |
class HttpClientWorkerPool(workerpool.WorkerPool): |
... | ... | |
1318 | 1333 |
|
1319 | 1334 |
|
1320 | 1335 |
class HttpClientManager(object): |
1336 |
"""Manages HTTP requests. |
|
1337 |
|
|
1338 |
""" |
|
1321 | 1339 |
def __init__(self): |
1322 | 1340 |
self._wpool = HttpClientWorkerPool(self) |
1323 | 1341 |
|
... | ... | |
1325 | 1343 |
self.Shutdown() |
1326 | 1344 |
|
1327 | 1345 |
def ExecRequests(self, requests): |
1328 |
# Add requests to queue |
|
1329 |
for req in requests: |
|
1330 |
self._wpool.AddTask(req) |
|
1346 |
"""Execute HTTP requests. |
|
1331 | 1347 |
|
1332 |
# And wait for them to finish |
|
1333 |
self._wpool.Quiesce() |
|
1348 |
This function can be called from multiple threads at the same time. |
|
1334 | 1349 |
|
1350 |
@type requests: List of HttpClientRequest instances |
|
1351 |
@param requests: The requests to execute |
|
1352 |
@rtype: List of HttpClientRequest instances |
|
1353 |
@returns: The list of requests passed in |
|
1354 |
|
|
1355 |
""" |
|
1356 |
# _HttpClientPendingRequest is used for internal thread synchronization |
|
1357 |
pending = [_HttpClientPendingRequest(req) for req in requests] |
|
1358 |
|
|
1359 |
try: |
|
1360 |
# Add requests to queue |
|
1361 |
for pend_req in pending: |
|
1362 |
self._wpool.AddTask(pend_req) |
|
1363 |
|
|
1364 |
finally: |
|
1365 |
# In case of an exception we should still wait for the rest, otherwise |
|
1366 |
# another thread from the worker pool could modify the request object |
|
1367 |
# after we returned. |
|
1368 |
|
|
1369 |
# And wait for them to finish |
|
1370 |
for pend_req in pending: |
|
1371 |
pend_req.done.wait() |
|
1372 |
|
|
1373 |
# Return original list |
|
1335 | 1374 |
return requests |
1336 | 1375 |
|
1337 | 1376 |
def Shutdown(self): |
1377 |
self._wpool.Quiesce() |
|
1338 | 1378 |
self._wpool.TerminateWorkers() |
1339 | 1379 |
|
1340 | 1380 |
|
Also available in: Unified diff