1
0
mirror of https://github.com/danog/dns.git synced 2024-11-30 04:29:06 +01:00

Move caching layer into client

This commit is contained in:
Chris Wright 2014-06-16 18:30:28 +01:00
parent f60ac3fc5e
commit 01b3d38c43
6 changed files with 34 additions and 71 deletions

View File

@ -13,10 +13,10 @@ interface Cache
* Look up a name in the cache
*
* @param string $name Name to query
* @param int $mode Bit mask of AddressModes
* @return array|null Array with address at index 0 and type at index 1, or null if the record does not exist
* @param int $type AddressModes::INET4_ADDR or AddressModes::INET6_ADDR
* @return string|null Mapped IP address or null or no record exists
*/
public function resolve($name, $mode);
public function resolve($name, $type);
/**
* Store an entry in the cache

View File

@ -21,6 +21,11 @@ class Client
*/
private $responseInterpreter;
/**
* @var Cache
*/
private $cache;
/**
* @var resource
*/
@ -67,6 +72,7 @@ class Client
* @param Reactor $reactor
* @param RequestBuilder $requestBuilder
* @param ResponseInterpreter $responseInterpreter
* @param Cache $cache
* @param string $serverAddress
* @param int $serverPort
* @param int $requestTimeout
@ -76,6 +82,7 @@ class Client
Reactor $reactor,
RequestBuilder $requestBuilder,
ResponseInterpreter $responseInterpreter,
Cache $cache = null,
$serverAddress = null,
$serverPort = null,
$requestTimeout = null
@ -83,6 +90,7 @@ class Client
$this->reactor = $reactor;
$this->requestBuilder = $requestBuilder;
$this->responseInterpreter = $responseInterpreter;
$this->cache = $cache;
$serverAddress = $serverAddress !== null ? (string)$serverAddress : '8.8.8.8';
$serverPort = $serverPort !== null ? (int)$serverPort : 53;
@ -216,8 +224,8 @@ class Client
}
if ($addr !== null) {
if ($request['cache_store']) {
call_user_func($request['cache_store'], $name, $addr, $type, $ttl);
if ($this->cache) {
$this->cache->store($name, $addr, $type, $ttl);
}
foreach ($request['lookups'] as $id => $lookup) {
@ -259,8 +267,13 @@ class Client
$name = $lookup['name'];
$type = array_shift($lookup['requests']);
$lookup['last_type'] = $type;
if ($this->cache && $addr = $this->cache->resolve($name, $type)) {
$this->completePendingLookup($id, $addr, $type);
return;
}
$lookup['last_type'] = $type;
$this->pendingRequestsByNameAndType[$name][$type]['lookups'][$id] = $lookup;
if (count($this->pendingRequestsByNameAndType[$name][$type]) === 1) {
@ -270,7 +283,6 @@ class Client
'type' => $type,
'lookups' => [$id => $lookup],
'timeout_id' => null,
'cache_store' => $lookup['cache_store'],
];
$this->sendRequest($request);
@ -283,9 +295,8 @@ class Client
* @param string $name
* @param int $mode
* @param callable $callback
* @param callable $cacheStore
*/
public function resolve($name, $mode, callable $callback, callable $cacheStore = null)
public function resolve($name, $mode, callable $callback)
{
$id = $this->getNextFreeLookupId();
@ -294,7 +305,6 @@ class Client
'requests' => $this->getRequestList($mode),
'last_type' => null,
'callback' => $callback,
'cache_store' => $cacheStore,
];
$this->processPendingLookup($id);

View File

@ -69,7 +69,7 @@ class HostsFile
foreach (file($this->path) as $line) {
$line = trim($line);
if ($line[0] === '#') {
if ($line !== '' && $line[0] === '#') {
continue;
}

View File

@ -15,31 +15,23 @@ class MemoryCache implements Cache
];
/**
* Look up a name in the cache
* Look up an entry in the cache
*
* @param string $name
* @param int $mode
* @param int $type
* @return string|null
*/
public function resolve($name, $mode)
public function resolve($name, $type)
{
$have4 = isset($this->data[AddressModes::INET4_ADDR][$name]);
$have6 = isset($this->data[AddressModes::INET6_ADDR][$name]);
if (isset($this->data[$type][$name])) {
if ($this->data[$type][$name][1] >= time()) {
return $this->data[$type][$name][0];
}
if ($have6 && (!$have4 || $mode & AddressModes::PREFER_INET6)) {
$type = AddressModes::INET6_ADDR;
} else if ($have4) {
$type = AddressModes::INET4_ADDR;
} else {
return null;
}
if ($this->data[$type][$name][1] < time()) {
unset($this->data[$type][$name]);
return null;
}
return [$this->data[$type][$name][0], $type];
return null;
}
/**

View File

@ -21,46 +21,29 @@ class Resolver
*/
private $client;
/**
* @var Cache
*/
private $cache;
/**
* @var HostsFile
*/
private $hostsFile;
/**
* @var callable
*/
private $cacheStoreCallback;
/**
* Constructor
*
* @param Reactor $reactor
* @param NameValidator $nameValidator
* @param Client $client
* @param Cache $cache
* @param HostsFile $hostsFile
*/
public function __construct(
Reactor $reactor,
NameValidator $nameValidator,
Client $client = null,
Cache $cache = null,
HostsFile $hostsFile = null
) {
$this->reactor = $reactor;
$this->nameValidator = $nameValidator;
$this->client = $client;
$this->cache = $cache;
$this->hostsFile = $hostsFile;
if ($cache) {
$this->cacheStoreCallback = [$cache, 'store'];
}
}
/**
@ -147,28 +130,6 @@ class Resolver
return true;
}
/**
* Resolve a name in the cache
*
* @param string $name
* @param int $mode
* @param callable $callback
* @return bool
*/
private function resolveInCache($name, $mode, $callback)
{
if ($this->cache && null !== $result = $this->cache->resolve($name, $mode)) {
list($addr, $type) = $result;
$this->reactor->immediately(function() use($callback, $addr, $type) {
call_user_func($callback, $addr, $type);
});
return true;
}
return false;
}
/**
* Resolve a name from a server
*
@ -187,7 +148,7 @@ class Resolver
return;
}
$this->client->resolve($name, $mode, $callback, $this->cacheStoreCallback);
$this->client->resolve($name, $mode, $callback);
}
/**
@ -208,7 +169,7 @@ class Resolver
return;
}
if ($this->resolveInHostsFile($name, $mode, $callback) || $this->resolveInCache($name, $mode, $callback)) {
if ($this->resolveInHostsFile($name, $mode, $callback)) {
return;
}

View File

@ -30,6 +30,7 @@ class ResolverFactory
$hostsFilePath = null
) {
$nameValidator = new NameValidator;
$cache = $cache ?: new MemoryCache;
$client = new Client(
$reactor,
@ -41,12 +42,11 @@ class ResolverFactory
new ResponseInterpreter(
(new DecoderFactory)->create()
),
$serverAddr, $serverPort, $requestTimeout
$cache, $serverAddr, $serverPort, $requestTimeout
);
$cache = $cache ?: new MemoryCache;
$hostsFile = new HostsFile($nameValidator, $hostsFilePath);
return new Resolver($reactor, $nameValidator, $client, $cache, $hostsFile);
return new Resolver($reactor, $nameValidator, $client, $hostsFile);
}
}