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