diff --git a/core/Files/AsyncHttpRequest.php b/core/Files/AsyncHttpRequest.php index 4fe45ca2..a7f5de4a 100644 --- a/core/Files/AsyncHttpRequest.php +++ b/core/Files/AsyncHttpRequest.php @@ -36,6 +36,7 @@ class AsyncHttpRequest implements UsageInformationAble { private $contentType = 'text/xml; charset=UTF-8;'; private $timeout = 60; private $headers = array(); + private $serialize = false; public function __construct($maniaControl, $url) { $this->maniaControl = $maniaControl; @@ -58,6 +59,7 @@ class AsyncHttpRequest implements UsageInformationAble { ->set(CURLOPT_RETURNTRANSFER, true)// ->set(CURLOPT_FOLLOWLOCATION, true)// support redirect ->set(CURLOPT_SSL_VERIFYPEER, false); + $request->setSerialize($this->serialize); // serialize requests to this host return $request; } @@ -228,4 +230,13 @@ class AsyncHttpRequest implements UsageInformationAble { public function setTimeout($timeout) { $this->timeout = $timeout; } + + /** + * Sets whether the request to the same host should be serialized. + * + * @param bool $serialize + */ + public function setSerialize($serialize = true) { + $this->serialize = $serialize; + } } \ No newline at end of file diff --git a/core/Files/AsynchronousFileReader.php b/core/Files/AsynchronousFileReader.php index 237f721d..a9c06ae8 100644 --- a/core/Files/AsynchronousFileReader.php +++ b/core/Files/AsynchronousFileReader.php @@ -23,6 +23,9 @@ class AsynchronousFileReader implements UsageInformationAble { */ const CONTENT_TYPE_JSON = 'application/json'; + const QUEUE_NONSERIALIZING = 0; + const QUEUE_SERIALIZING = 1; + /* * Private properties */ @@ -30,7 +33,7 @@ class AsynchronousFileReader implements UsageInformationAble { private $maniaControl = null; /** @var \cURL\RequestsQueue|null $requestQueue */ - private $requestQueue = null; + private $requestQueue = array(null, null); /** * Construct a new Asynchronous File Reader Instance @@ -39,22 +42,30 @@ class AsynchronousFileReader implements UsageInformationAble { */ public function __construct(ManiaControl $maniaControl) { $this->maniaControl = $maniaControl; - $this->requestQueue = new RequestsQueue(); + + // Queue for non-serializing requests (parallel is preferred) + $this->requestQueue[self::QUEUE_NONSERIALIZING] = new RequestsQueue(); + + // Queue for per host serialized requests + $this->requestQueue[self::QUEUE_SERIALIZING] = new RequestsQueue(); + $this->requestQueue[self::QUEUE_SERIALIZING]->setOption(CURLMOPT_MAX_HOST_CONNECTIONS, 1); } /** * Append available Data of active Requests */ public function appendData() { - do { - if (($count = $this->requestQueue->count()) == 0) { - break; - } + foreach ($this->requestQueue as &$queue) { + do { + if (($count = $queue->count()) == 0) { + break; + } - if ($this->requestQueue->socketPerform()) { - $this->requestQueue->socketSelect(); - } - } while ($count != $this->requestQueue->count()); + if ($queue->socketPerform()) { + $queue->socketSelect(); + } + } while ($count != $queue->count()); + } } /** @@ -96,6 +107,10 @@ class AsynchronousFileReader implements UsageInformationAble { * @param Request $request */ public function addRequest(Request $request) { - $request->attachTo($this->requestQueue); + $queueId = $request->getSerialize() + ? self::QUEUE_SERIALIZING + : self::QUEUE_NONSERIALIZING; + $queue = $this->requestQueue[$queueId]; + $request->attachTo($queue); } } diff --git a/libs/curl-easy/cURL/Request.php b/libs/curl-easy/cURL/Request.php index 6fb263b0..8b174dd9 100644 --- a/libs/curl-easy/cURL/Request.php +++ b/libs/curl-easy/cURL/Request.php @@ -19,6 +19,11 @@ class Request extends EventDispatcher implements RequestInterface * @var Options Object containing options for current request */ protected $options = null; + + /** + * @var bool Whether requests to the target host should be serialized or not. + */ + protected $serializeRequests = false; /** * Create new cURL handle @@ -121,7 +126,8 @@ class Request extends EventDispatcher implements RequestInterface * @param \cURL\RequestsQueue $requestsQueue * @throws \cURL\Exception */ - public function attachTo(RequestsQueue $requestsQueue) { + public function attachTo(RequestsQueue $requestsQueue) + { if (isset($this->queue)) { throw new Exception('Already bound to a RequestQueue.'); } @@ -129,6 +135,24 @@ class Request extends EventDispatcher implements RequestInterface $this->queue->attach($this); } + /** + * Whether to serialize requests to the same host or not. + * + * @param bool $serialize + */ + public function setSerialize($serialize = true) + { + $this->serializeRequests = $serialize; + } + + /** + * @return bool + */ + public function getSerialize() + { + return $this->serializeRequests; + } + /** * Creates new RequestsQueue with single Request attached to it * and calls RequestsQueue::socketPerform() method. diff --git a/libs/curl-easy/cURL/RequestsQueue.php b/libs/curl-easy/cURL/RequestsQueue.php index 4b99826b..25864fc2 100644 --- a/libs/curl-easy/cURL/RequestsQueue.php +++ b/libs/curl-easy/cURL/RequestsQueue.php @@ -217,4 +217,12 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, \ } return curl_multi_select($this->mh, $timeout) !== -1; } + + /** + * @param $option + * @param $value + */ + public function setOption($option, $value) { + curl_multi_setopt($this->mh, $option, $value); + } } diff --git a/plugins/MCTeam/Dedimania/DedimaniaWebHandler.php b/plugins/MCTeam/Dedimania/DedimaniaWebHandler.php index 22522c71..f80bb980 100644 --- a/plugins/MCTeam/Dedimania/DedimaniaWebHandler.php +++ b/plugins/MCTeam/Dedimania/DedimaniaWebHandler.php @@ -83,6 +83,7 @@ class DedimaniaWebHandler implements TimerListener { $asyncHttpRequest->setContent($content); $asyncHttpRequest->setCompression(true); $asyncHttpRequest->setTimeout(500); + $asyncHttpRequest->setSerialize(); $asyncHttpRequest->postData(); } @@ -171,6 +172,7 @@ class DedimaniaWebHandler implements TimerListener { $asyncHttpRequest->setContent($content); $asyncHttpRequest->setCompression(true); $asyncHttpRequest->setTimeout(500); + $asyncHttpRequest->setSerialize(); $asyncHttpRequest->postData(); return true; @@ -218,6 +220,7 @@ class DedimaniaWebHandler implements TimerListener { $asyncHttpRequest->setContent($content); $asyncHttpRequest->setCompression(true); $asyncHttpRequest->setTimeout(500); + $asyncHttpRequest->setSerialize(); $asyncHttpRequest->postData(); } @@ -309,6 +312,7 @@ class DedimaniaWebHandler implements TimerListener { $asyncHttpRequest->setContent($content); $asyncHttpRequest->setCompression(false); $asyncHttpRequest->setTimeout(500); + $asyncHttpRequest->setSerialize(); $asyncHttpRequest->postData(); } @@ -361,6 +365,7 @@ class DedimaniaWebHandler implements TimerListener { $asyncHttpRequest->setContent($content); $asyncHttpRequest->setCompression(true); $asyncHttpRequest->setTimeout(500); + $asyncHttpRequest->setSerialize(); $asyncHttpRequest->postData(); } @@ -403,6 +408,7 @@ class DedimaniaWebHandler implements TimerListener { $asyncHttpRequest->setContent($content); $asyncHttpRequest->setCompression(true); $asyncHttpRequest->setTimeout(500); + $asyncHttpRequest->setSerialize(); $asyncHttpRequest->postData(); } @@ -447,6 +453,7 @@ class DedimaniaWebHandler implements TimerListener { $asyncHttpRequest->setContent($content); $asyncHttpRequest->setCompression(true); $asyncHttpRequest->setTimeout(500); + $asyncHttpRequest->setSerialize(); $asyncHttpRequest->postData(); }