Skip to content

Commit

Permalink
feat: cache & requestTimeout
Browse files Browse the repository at this point in the history
  • Loading branch information
YellowPhoenix18 committed Feb 18, 2021
1 parent e9cd0df commit f8630c6
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 18 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
vendor
vendor
index.php
web/cache/*
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"name": "syntaxphoenix/bgpview-php",
"version": "0.0.1",
"version": "0.0.2",
"type": "framework",
"autoload": {
"psr-4": {
"SyntaxPhoenix\\Api\\BGPView\\" : "src/"
}
},
"require": {
"guzzlehttp/guzzle": "7.0"
"guzzlehttp/guzzle": "7.0",
"nette/caching": "^3.1"
}
}
225 changes: 224 additions & 1 deletion composer.lock

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

71 changes: 57 additions & 14 deletions src/BGPView.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,112 @@
namespace SyntaxPhoenix\Api\BGPView;

use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;
use Nette\Caching\Cache;
use Nette\Caching\Storage;
use Nette\Caching\Storages\FileStorage;
use SyntaxPhoenix\Api\BGPView\Exceptions\RequestFailedException;

class BGPView
{

private string $baseUrl;
private bool $caching;
private Client $client;
private Storage $storage;
private Cache $cache;
private string $cacheTime;
private float $lastRequestTimestamp = 0;
private float $requestTimeout;

public function __construct(string $baseUrl) {
public function __construct(string $baseUrl, float $requestTimeout = 0.4, bool $caching = false, ?string $cachingUrl = 'web/cache/bgpview', ?string $cacheTime = '10 minutes') {
if ($caching) {
$this->createPath($cachingUrl);
$this->storage = new FileStorage($cachingUrl);
$this->cache = new Cache($this->storage, 'bgpview-requests');
}
$this->baseUrl = $baseUrl;
$this->caching = $caching;
$this->cacheTime = $cacheTime;
$this->requestTimeout = $requestTimeout;
$this->client = new Client([
'base_uri' => $baseUrl,
'timeout' => 2.0,
'base_uri' => $baseUrl
]);
}

public function getAsnDetails(int $asNumber): array
{
return json_decode($this->getDataByApi('asn/' . $asNumber)->getBody(), true)['data'];
return $this->getDataByApi('asn/' . $asNumber)['data'];
}

public function getAsnPrefixes(int $asNumber): array
{
return json_decode($this->getDataByApi('asn/' . $asNumber . '/prefixes')->getBody(), true)['data'];
return $this->getDataByApi('asn/' . $asNumber . '/prefixes')['data'];
}

public function getAsnPeers(int $asNumber): array
{
return json_decode($this->getDataByApi('asn/' . $asNumber . '/peers')->getBody(), true)['data'];
return $this->getDataByApi('asn/' . $asNumber . '/peers')['data'];
}

public function getAsnUpstreams(int $asNumber): array
{
return json_decode($this->getDataByApi('asn/' . $asNumber . '/upstreams')->getBody(), true)['data'];
return $this->getDataByApi('asn/' . $asNumber . '/upstreams')['data'];
}

public function getAsnDownstreams(int $asNumber): array
{
return json_decode($this->getDataByApi('asn/' . $asNumber . '/downstreams')->getBody(), true)['data'];
return $this->getDataByApi('asn/' . $asNumber . '/downstreams')['data'];
}

public function getPrefix(string $ipAddress, int $cidr): array
{
return json_decode($this->getDataByApi('prefix/' . $ipAddress . '/' . $cidr)->getBody(), true)['data'];
return $this->getDataByApi('prefix/' . $ipAddress . '/' . $cidr)['data'];
}

public function getIPDetails(string $ipAddress): array
{
return json_decode($this->getDataByApi('prefix/ip/' . $ipAddress)->getBody(), true)['data'];
return $this->getDataByApi('ip/' . $ipAddress)['data'];
}

public function getIXDetails(int $ixId): array
{
return json_decode($this->getDataByApi('ix/' . $ixId)->getBody(), true)['data'];
return $this->getDataByApi('ix/' . $ixId)['data'];
}

private function getDataByApi(string $urlPart): ResponseInterface
private function getDataByApi(string $urlPart): array
{
if ($this->caching) {
$response = $this->cache->load($urlPart);
if ($response) {
return $response;
}
}
$time = microtime(true);
if (($this->lastRequestTimestamp + $this->requestTimeout) > $time) {
$restTime = $this->requestTimeout - ($time - $this->lastRequestTimestamp);
usleep($restTime * 1000 * 1000);
}
$response = $this->client->request('GET', $urlPart);
if ($response->getStatusCode() != 200) {
throw new RequestFailedException();
}
return $response;
$finalResponse = json_decode($response->getBody(), true);
if ($this->caching) {
$this->cache->save($urlPart, $finalResponse, [
Cache::EXPIRE => $this->cacheTime ?? '10 minutes',
]);
}
$this->lastRequestTimestamp = microtime(true);

return $finalResponse;
}

private function createPath($path) {
if (is_dir($path)) {
return true;
}
$prev_path = substr($path, 0, strrpos($path, '/', -2) + 1 );
$return = $this->createPath($prev_path);
return ($return && is_writable($prev_path)) ? mkdir($path) : false;
}
}

0 comments on commit f8630c6

Please sign in to comment.