Skip to content

Commit

Permalink
Merge pull request #27 from Exanlv/master
Browse files Browse the repository at this point in the history
Crude implementation to allow Promise V3
  • Loading branch information
valzargaming authored Nov 19, 2024
2 parents 6186d74 + 0636a7a commit 017322d
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 26 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"php": "^7.4|^8.0",
"react/http": "^1.2",
"psr/log": "^1.1 || ^2.0 || ^3.0",
"react/promise": "^2.2"
"react/promise": "^2.2 || ^3.0.0"
},
"suggest": {
"guzzlehttp/guzzle": "For alternative to ReactPHP/Http Browser"
Expand Down
13 changes: 12 additions & 1 deletion src/Discord/Bucket.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Discord\Http;

use Composer\InstalledVersions;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use React\EventLoop\LoopInterface;
Expand Down Expand Up @@ -87,6 +88,11 @@ class Bucket
*/
protected $resetTimer;

/**
* Whether react/promise v3 is used, if false, using v2
*/
protected $promiseV3 = true;

/**
* Bucket constructor.
*
Expand All @@ -100,6 +106,10 @@ public function __construct(string $name, LoopInterface $loop, LoggerInterface $
$this->loop = $loop;
$this->logger = $logger;
$this->runRequest = $runRequest;

if (str_starts_with(InstalledVersions::getVersion('react/promise'), '0.3.')) {
$this->promiseV3 = true;
}
}

/**
Expand Down Expand Up @@ -149,7 +159,8 @@ public function checkQueue()
/** @var Request */
$request = $this->queue->dequeue();

($this->runRequest)($request)->done(function (ResponseInterface $response) use (&$checkQueue) {
// Promises v3 changed `->then` to behave as `->done` and removed `->then`. We still need the behaviour of `->done` in projects using v2
($this->runRequest)($request)->{$this->promiseV3 ? 'then' : 'done'}(function (ResponseInterface $response) use (&$checkQueue) {
$resetAfter = (float) $response->getHeaderLine('X-Ratelimit-Reset-After');
$limit = $response->getHeaderLine('X-Ratelimit-Limit');
$remaining = $response->getHeaderLine('X-Ratelimit-Remaining');
Expand Down
6 changes: 3 additions & 3 deletions src/Discord/DriverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Discord\Http;

use Psr\Http\Message\ResponseInterface;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;

/**
* Interface for an HTTP driver.
Expand All @@ -28,7 +28,7 @@ interface DriverInterface
*
* @param Request $request
*
* @return ExtendedPromiseInterface<ResponseInterface>
* @return PromiseInterface<ResponseInterface>
*/
public function runRequest(Request $request): ExtendedPromiseInterface;
public function runRequest(Request $request): PromiseInterface;
}
4 changes: 2 additions & 2 deletions src/Discord/Drivers/Guzzle.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use GuzzleHttp\RequestOptions;
use React\EventLoop\LoopInterface;
use React\Promise\Deferred;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;

/**
* guzzlehttp/guzzle driver for Discord HTTP client. (still with React Promise).
Expand Down Expand Up @@ -55,7 +55,7 @@ public function __construct(?LoopInterface $loop = null, array $options = [])
$this->client = new Client($options);
}

public function runRequest(Request $request): ExtendedPromiseInterface
public function runRequest(Request $request): PromiseInterface
{
// Create a React promise
$deferred = new Deferred();
Expand Down
4 changes: 2 additions & 2 deletions src/Discord/Drivers/React.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Discord\Http\Request;
use React\EventLoop\LoopInterface;
use React\Http\Browser;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;
use React\Socket\Connector;

/**
Expand Down Expand Up @@ -54,7 +54,7 @@ public function __construct(LoopInterface $loop, array $options = [])
$this->browser = $browser->withRejectErrorResponse(false);
}

public function runRequest(Request $request): ExtendedPromiseInterface
public function runRequest(Request $request): PromiseInterface
{
return $this->browser->{$request->getMethod()}(
$request->getUrl(),
Expand Down
44 changes: 28 additions & 16 deletions src/Discord/Http.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Discord\Http;

use Composer\InstalledVersions;
use Discord\Http\Exceptions\BadRequestException;
use Discord\Http\Exceptions\ContentTooLongException;
use Discord\Http\Exceptions\InvalidTokenException;
Expand All @@ -24,7 +25,7 @@
use Psr\Log\LoggerInterface;
use React\EventLoop\LoopInterface;
use React\Promise\Deferred;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;
use SplQueue;

/**
Expand Down Expand Up @@ -127,6 +128,12 @@ class Http
*/
protected $waiting = 0;


/**
* Whether react/promise v3 is used, if false, using v2
*/
protected $promiseV3 = true;

/**
* Http wrapper constructor.
*
Expand All @@ -141,6 +148,10 @@ public function __construct(string $token, LoopInterface $loop, LoggerInterface
$this->logger = $logger;
$this->driver = $driver;
$this->queue = new SplQueue;

if (str_starts_with(InstalledVersions::getVersion('react/promise'), '0.3.')) {
$this->promiseV3 = true;
}
}

/**
Expand All @@ -160,9 +171,9 @@ public function setDriver(DriverInterface $driver): void
* @param mixed $content
* @param array $headers
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
public function get($url, $content = null, array $headers = []): ExtendedPromiseInterface
public function get($url, $content = null, array $headers = []): PromiseInterface
{
if (! ($url instanceof Endpoint)) {
$url = Endpoint::bind($url);
Expand All @@ -178,9 +189,9 @@ public function get($url, $content = null, array $headers = []): ExtendedPromise
* @param mixed $content
* @param array $headers
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
public function post($url, $content = null, array $headers = []): ExtendedPromiseInterface
public function post($url, $content = null, array $headers = []): PromiseInterface
{
if (! ($url instanceof Endpoint)) {
$url = Endpoint::bind($url);
Expand All @@ -196,9 +207,9 @@ public function post($url, $content = null, array $headers = []): ExtendedPromis
* @param mixed $content
* @param array $headers
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
public function put($url, $content = null, array $headers = []): ExtendedPromiseInterface
public function put($url, $content = null, array $headers = []): PromiseInterface
{
if (! ($url instanceof Endpoint)) {
$url = Endpoint::bind($url);
Expand All @@ -214,9 +225,9 @@ public function put($url, $content = null, array $headers = []): ExtendedPromise
* @param mixed $content
* @param array $headers
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
public function patch($url, $content = null, array $headers = []): ExtendedPromiseInterface
public function patch($url, $content = null, array $headers = []): PromiseInterface
{
if (! ($url instanceof Endpoint)) {
$url = Endpoint::bind($url);
Expand All @@ -232,9 +243,9 @@ public function patch($url, $content = null, array $headers = []): ExtendedPromi
* @param mixed $content
* @param array $headers
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
public function delete($url, $content = null, array $headers = []): ExtendedPromiseInterface
public function delete($url, $content = null, array $headers = []): PromiseInterface
{
if (! ($url instanceof Endpoint)) {
$url = Endpoint::bind($url);
Expand All @@ -251,9 +262,9 @@ public function delete($url, $content = null, array $headers = []): ExtendedProm
* @param mixed $content
* @param array $headers
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
public function queueRequest(string $method, Endpoint $url, $content, array $headers = []): ExtendedPromiseInterface
public function queueRequest(string $method, Endpoint $url, $content, array $headers = []): PromiseInterface
{
$deferred = new Deferred();

Expand Down Expand Up @@ -318,9 +329,9 @@ protected function guessContent(&$content)
* @param Request $request
* @param Deferred $deferred
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
protected function executeRequest(Request $request, Deferred $deferred = null): ExtendedPromiseInterface
protected function executeRequest(Request $request, Deferred $deferred = null): PromiseInterface
{
if ($deferred === null) {
$deferred = new Deferred();
Expand All @@ -332,7 +343,8 @@ protected function executeRequest(Request $request, Deferred $deferred = null):
return $deferred->promise();
}

$this->driver->runRequest($request)->done(function (ResponseInterface $response) use ($request, $deferred) {
// Promises v3 changed `->then` to behave as `->done` and removed `->then`. We still need the behaviour of `->done` in projects using v2
$this->driver->runRequest($request)->{$this->promiseV3 ? 'then' : 'done'}(function (ResponseInterface $response) use ($request, $deferred) {
$data = json_decode((string) $response->getBody());
$statusCode = $response->getStatusCode();

Expand Down
4 changes: 3 additions & 1 deletion src/Discord/RateLimit.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

namespace Discord\Http;

use RuntimeException;

/**
* Represents a rate-limit given by Discord.
*
* @author David Cole <[email protected]>
*/
class RateLimit
class RateLimit extends RuntimeException
{
/**
* Whether the rate-limit is global.
Expand Down

0 comments on commit 017322d

Please sign in to comment.