Skip to content
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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"php": "^7.0",
"api-clients/client-services": "dev-master",
"api-clients/foundation": "dev-master",
"api-clients/middleware": "^2.0",
"api-clients/middleware-http-exceptions": "^1.0",
"api-clients/middleware-token-authorization": "^2.0",
"api-clients/middleware-user-agent": "^1.0",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions examples/my-organizations-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@
}, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
8 changes: 8 additions & 0 deletions examples/resolve_token.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use ApiClients\Client\Github\Authentication\Anonymous;
use ApiClients\Client\Github\Authentication\Token;
use ApiClients\Client\Github\RateLimitState;

$keyFile = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'token.php';

Expand All @@ -14,6 +15,13 @@ function display_throwable(Throwable $throwable)
echo (string) $throwable, PHP_EOL;
}

function displayState(RateLimitState $state) {
echo 'Rate Limit State: ', PHP_EOL;
echo "\t", 'Limit: ', $state->getLimit(), PHP_EOL;
echo "\t", 'Remaining: ', $state->getRemaining(), PHP_EOL;
echo "\t", 'Reset: ', date(DATE_RFC2822, $state->getReset()), PHP_EOL;
}

//return new Anonymous();

if (!file_exists($keyFile)) {
Expand Down
2 changes: 2 additions & 0 deletions examples/user-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@
}

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-organizations-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-add-label-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@
}, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-branches-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-commit-combined-status-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-commit-status-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-commits-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-contents-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-first-file-contents-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories-labels-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@
})->done(null, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repositories.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@
echo "\t\t" . 'name: ' . $repository->name(), PHP_EOL;
echo "\t\t" . 'fork: ' . (int)$repository->fork(), PHP_EOL;
}

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user-repository-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@
}, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
foreach ($users as $user) {
resource_pretty_print($client->user($user));
}

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions examples/whoami-async.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@
}, 'display_throwable');

$loop->run();

displayState($client->getRateLimitState());
2 changes: 2 additions & 0 deletions src/ApiSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace ApiClients\Client\Github;

use ApiClients\Client\Github\Middleware\RateLimitStateMiddleware;
use ApiClients\Foundation\Hydrator\Options as HydratorOptions;
use ApiClients\Foundation\Options as FoundationOptions;
use ApiClients\Foundation\Transport\Middleware\JsonDecodeMiddleware;
Expand Down Expand Up @@ -29,6 +30,7 @@ final class ApiSettings
JsonEncodeMiddleware::class,
HttpExceptionsMiddleware::class,
UserAgentMiddleware::class,
RateLimitStateMiddleware::class,
],
TransportOptions::DEFAULT_REQUEST_OPTIONS => [
UserAgentMiddleware::class => [
Expand Down
22 changes: 20 additions & 2 deletions src/AsyncClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use ApiClients\Client\Github\CommandBus\Command;
use ApiClients\Foundation\ClientInterface;
use ApiClients\Foundation\Factory;
use ApiClients\Foundation\Options;
use React\EventLoop\LoopInterface;
use React\Promise\PromiseInterface;
use Rx\Observable;
Expand All @@ -19,6 +20,11 @@ final class AsyncClient implements AsyncClientInterface
*/
private $client;

/**
* @var RateLimitState
*/
private $rateLimitState;

/**
* @param LoopInterface $loop
* @param AuthenticationInterface $auth
Expand All @@ -31,6 +37,8 @@ public static function create(
array $options = []
): self {
$options = ApiSettings::getOptions($auth, $options, 'Async');
$rateLimitState = new RateLimitState();
$options[Options::CONTAINER_DEFINITIONS][RateLimitState::class] = $rateLimitState;
$client = Factory::create($loop, $options);

try {
Expand All @@ -40,15 +48,17 @@ public static function create(
} catch (\Throwable $t) {
}

return new self($client);
return new self($client, $rateLimitState);
}

/**
* @param ClientInterface $client
* @param RateLimitState $rateLimitState
*/
private function __construct(ClientInterface $client)
private function __construct(ClientInterface $client, RateLimitState $rateLimitState)
{
$this->client = $client;
$this->rateLimitState = $rateLimitState;
}

public function user(string $user): PromiseInterface
Expand All @@ -65,4 +75,12 @@ public function myOrganizations(): Observable
{
return unwrapObservableFromPromise($this->client->handle(new Command\MyOrganizationsCommand()));
}

/**
* @return RateLimitState
*/
public function getRateLimitState(): RateLimitState
{
return clone $this->rateLimitState;
}
}
2 changes: 2 additions & 0 deletions src/AsyncClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public function user(string $user): PromiseInterface;
public function whoami(): PromiseInterface;

public function myOrganizations(): Observable;

public function getRateLimitState(): RateLimitState;
}
5 changes: 5 additions & 0 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ public function user(string $user): UserInterface
$this->loop
);
}

public function getRateLimitState(): RateLimitState
{
return $this->client->getRateLimitState();
}
}
2 changes: 2 additions & 0 deletions src/ClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@
interface ClientInterface
{
public function user(string $user): UserInterface;

public function getRateLimitState(): RateLimitState;
}
57 changes: 57 additions & 0 deletions src/Middleware/RateLimitStateMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php declare(strict_types=1);

namespace ApiClients\Client\Github\Middleware;

use ApiClients\Client\Github\RateLimitState;
use ApiClients\Foundation\Middleware\DefaultPriorityTrait;
use ApiClients\Foundation\Middleware\ErrorTrait;
use ApiClients\Foundation\Middleware\MiddlewareInterface;
use ApiClients\Foundation\Middleware\PreTrait;
use Psr\Http\Message\ResponseInterface;
use React\Promise\CancellablePromiseInterface;
use function React\Promise\resolve;

final class RateLimitStateMiddleware implements MiddlewareInterface
{
use DefaultPriorityTrait;
use PreTrait;
use ErrorTrait;

const HEADERS = [
'X-RateLimit-Limit' => 'setLimit',
'X-RateLimit-Remaining' => 'setRemaining',
'X-RateLimit-Reset' => 'setReset',
];

/**
* @var RateLimitState
*/
private $state;

/**
* RateLimitStatusMiddleware constructor.
* @param RateLimitState $state
*/
public function __construct(RateLimitState $state)
{
$this->state = $state;
}

/**
* @param ResponseInterface $response
* @param array $options
* @return CancellablePromiseInterface
*/
public function post(ResponseInterface $response, array $options = []): CancellablePromiseInterface
{
foreach (self::HEADERS as $header => $method) {
if (!$response->hasHeader($header)) {
continue;
}

$this->state->$method((int)$response->getHeaderLine($header));
}

return resolve($response);
}
}
69 changes: 69 additions & 0 deletions src/RateLimitState.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php declare(strict_types=1);

namespace ApiClients\Client\Github;

final class RateLimitState
{
/**
* @var int
*/
private $limit = 0;

/**
* @var int
*/
private $remaining = 0;

/**
* @var int
*/
private $reset = 0;

/**
* @return int
*/
public function getLimit(): int
{
return $this->limit;
}

/**
* @param int $limit
*/
public function setLimit(int $limit)
{
$this->limit = $limit;
}

/**
* @return int
*/
public function getRemaining(): int
{
return $this->remaining;
}

/**
* @param int $remaining
*/
public function setRemaining(int $remaining)
{
$this->remaining = $remaining;
}

/**
* @return int
*/
public function getReset(): int
{
return $this->reset;
}

/**
* @param int $reset
*/
public function setReset(int $reset)
{
$this->reset = $reset;
}
}
17 changes: 17 additions & 0 deletions tests/AsyncClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php declare(strict_types=1);

namespace ApiClients\Client\Github;

use ApiClients\Client\Github\Authentication\Anonymous;
use ApiClients\Tools\TestUtilities\TestCase;
use React\EventLoop\Factory;

final class AsyncClientTest extends TestCase
{
public function testGetRateLimitState()
{
$loop = Factory::create();
$client = AsyncClient::create($loop, new Anonymous());
self::assertInstanceOf(RateLimitState::class, $client->getRateLimitState());
}
}
15 changes: 15 additions & 0 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);

namespace ApiClients\Client\Github;

use ApiClients\Client\Github\Authentication\Anonymous;
use ApiClients\Tools\TestUtilities\TestCase;

final class ClientTest extends TestCase
{
public function testGetRateLimitState()
{
$client = new Client(new Anonymous());
self::assertInstanceOf(RateLimitState::class, $client->getRateLimitState());
}
}
Loading