Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crude implementation to allow Promise V3 #27

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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