Implemented strict http request serialization for APIs that forbid a session to be used in concurrent requests (e.g. dedimania).

Updated all API requests in DedimaniaPlugin to be serialized by this mechanism. Closes #139.
This commit is contained in:
Sebastian Büttner
2017-05-22 22:32:15 +02:00
parent d03f155415
commit b0732bee96
5 changed files with 77 additions and 12 deletions

View File

@ -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;
}
}

View File

@ -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);
}
}