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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ $loop->run();
If the first call returns before the second, only one query will be executed.
The second result will be served from cache.

### Custom cache adapter

By default, the above will use an in memory cache.

You can also specify a custom cache implementing [`CacheInterface`](https://github.com/reactphp/cache) to handle the record cache instead:

```php
$cache = new React\Cache\ArrayCache();
$loop = React\EventLoop\Factory::create();
$factory = new React\Dns\Resolver\Factory();
$dns = $factory->createCached('8.8.8.8', $loop, $cache);
```

See also the wiki for possible [cache implementations](https://github.com/reactphp/react/wiki/Users#cache-implementations).

## Install

The recommended way to install this library is [through Composer](http://getcomposer.org).
Expand Down
13 changes: 9 additions & 4 deletions src/Resolver/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace React\Dns\Resolver;

use React\Cache\ArrayCache;
use React\Cache\CacheInterface;
use React\Dns\Query\Executor;
use React\Dns\Query\CachedExecutor;
use React\Dns\Query\RecordCache;
Expand All @@ -21,10 +22,14 @@ public function create($nameserver, LoopInterface $loop)
return new Resolver($nameserver, $executor);
}

public function createCached($nameserver, LoopInterface $loop)
public function createCached($nameserver, LoopInterface $loop, CacheInterface $cache = null)
{
if (!($cache instanceof CacheInterface)) {
$cache = new ArrayCache();
}

$nameserver = $this->addPortToServerIfMissing($nameserver);
$executor = $this->createCachedExecutor($loop);
$executor = $this->createCachedExecutor($loop, $cache);

return new Resolver($nameserver, $executor);
}
Expand All @@ -39,9 +44,9 @@ protected function createRetryExecutor(LoopInterface $loop)
return new RetryExecutor($this->createExecutor($loop));
}

protected function createCachedExecutor(LoopInterface $loop)
protected function createCachedExecutor(LoopInterface $loop, CacheInterface $cache)
{
return new CachedExecutor($this->createRetryExecutor($loop), new RecordCache(new ArrayCache()));
return new CachedExecutor($this->createRetryExecutor($loop), new RecordCache($cache));
}

protected function addPortToServerIfMissing($nameserver)
Expand Down
39 changes: 38 additions & 1 deletion tests/Resolver/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,30 @@ public function createCachedShouldCreateResolverWithCachedExecutor()
$resolver = $factory->createCached('8.8.8.8:53', $loop);

$this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver);
$this->assertInstanceOf('React\Dns\Query\CachedExecutor', $this->getResolverPrivateMemberValue($resolver, 'executor'));
$executor = $this->getResolverPrivateMemberValue($resolver, 'executor');
$this->assertInstanceOf('React\Dns\Query\CachedExecutor', $executor);
$recordCache = $this->getCachedExecutorPrivateMemberValue($executor, 'cache');
$recordCacheCache = $this->getRecordCachePrivateMemberValue($recordCache, 'cache');
$this->assertInstanceOf('React\Cache\CacheInterface', $recordCacheCache);
$this->assertInstanceOf('React\Cache\ArrayCache', $recordCacheCache);
}

/** @test */
public function createCachedShouldCreateResolverWithCachedExecutorWithCustomCache()
{
$cache = $this->getMock('React\Cache\CacheInterface');
$loop = $this->getMock('React\EventLoop\LoopInterface');

$factory = new Factory();
$resolver = $factory->createCached('8.8.8.8:53', $loop, $cache);

$this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver);
$executor = $this->getResolverPrivateMemberValue($resolver, 'executor');
$this->assertInstanceOf('React\Dns\Query\CachedExecutor', $executor);
$recordCache = $this->getCachedExecutorPrivateMemberValue($executor, 'cache');
$recordCacheCache = $this->getRecordCachePrivateMemberValue($recordCache, 'cache');
$this->assertInstanceOf('React\Cache\CacheInterface', $recordCacheCache);
$this->assertSame($cache, $recordCacheCache);
}

/**
Expand Down Expand Up @@ -75,4 +98,18 @@ private function getResolverPrivateMemberValue($resolver, $field)
$reflector->setAccessible(true);
return $reflector->getValue($resolver);
}

private function getCachedExecutorPrivateMemberValue($resolver, $field)
{
$reflector = new \ReflectionProperty('React\Dns\Query\CachedExecutor', $field);
$reflector->setAccessible(true);
return $reflector->getValue($resolver);
}

private function getRecordCachePrivateMemberValue($resolver, $field)
{
$reflector = new \ReflectionProperty('React\Dns\Query\RecordCache', $field);
$reflector->setAccessible(true);
return $reflector->getValue($resolver);
}
}