Skip to content

Commit b3207b5

Browse files
authored
Interaction endpoints bypass concurrency limit
2 parents 5ebb100 + e473c6f commit b3207b5

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

src/Discord/Http.php

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ class Http
121121
*/
122122
protected $queue;
123123

124+
/**
125+
* Request queue to prevent API
126+
* overload.
127+
*
128+
* @var SplQueue
129+
*/
130+
protected $interactionQueue;
131+
124132
/**
125133
* Number of requests that are waiting for a response.
126134
*
@@ -148,6 +156,7 @@ public function __construct(string $token, LoopInterface $loop, LoggerInterface
148156
$this->logger = $logger;
149157
$this->driver = $driver;
150158
$this->queue = new SplQueue;
159+
$this->interactionQueue = new SplQueue;
151160

152161
$this->promiseV3 = str_starts_with(InstalledVersions::getVersion('react/promise'), '3.');
153162
}
@@ -451,7 +460,9 @@ protected function getBucket(string $key): Bucket
451460
if (! isset($this->buckets[$key])) {
452461
$bucket = new Bucket($key, $this->loop, $this->logger, function (Request $request) {
453462
$deferred = new Deferred();
454-
$this->queue->enqueue([$request, $deferred]);
463+
self::isInteractionEndpoint($request)
464+
? $this->interactionQueue->enqueue([$request, $deferred])
465+
: $this->queue->enqueue([$request, $deferred]);
455466
$this->checkQueue();
456467

457468
return $deferred->promise();
@@ -469,8 +480,10 @@ protected function getBucket(string $key): Bucket
469480
*/
470481
protected function checkQueue(): void
471482
{
483+
$this->checkInteractionQueue();
484+
472485
if ($this->waiting >= static::CONCURRENT_REQUESTS || $this->queue->isEmpty()) {
473-
$this->logger->debug('http not checking', ['waiting' => $this->waiting, 'empty' => $this->queue->isEmpty()]);
486+
$this->logger->debug('http not checking queue', ['waiting' => $this->waiting, 'empty' => $this->queue->isEmpty()]);
474487

475488
return;
476489
}
@@ -493,6 +506,47 @@ protected function checkQueue(): void
493506
});
494507
}
495508

509+
/**
510+
* Checks the interaction queue to see if more requests can be
511+
* sent out.
512+
*/
513+
protected function checkInteractionQueue(): void
514+
{
515+
if ($this->interactionQueue->isEmpty()) {
516+
$this->logger->debug('http not checking interaction queue', ['waiting' => $this->waiting, 'empty' => $this->interactionQueue->isEmpty()]);
517+
518+
return;
519+
}
520+
521+
/**
522+
* @var Request $request
523+
* @var Deferred $deferred
524+
*/
525+
[$request, $deferred] = $this->interactionQueue->dequeue();
526+
527+
$this->executeRequest($request)->then(function ($result) use ($deferred) {
528+
$this->checkQueue();
529+
$deferred->resolve($result);
530+
}, function ($e) use ($deferred) {
531+
$this->checkQueue();
532+
$deferred->reject($e);
533+
});
534+
}
535+
536+
/**
537+
* Checks if the request is for an interaction endpoint.
538+
*
539+
* @link https://discord.com/developers/docs/interactions/receiving-and-responding#endpoints
540+
*
541+
* @param Request $request
542+
* @return bool
543+
*/
544+
public static function isInteractionEndpoint(Request $request): bool
545+
{
546+
$endpoint = (string) $request->getUrl();
547+
return strpos($endpoint, '/interactions') === 0;
548+
}
549+
496550
/**
497551
* Returns an exception based on the request.
498552
*

0 commit comments

Comments
 (0)