mirror of
https://github.com/danog/dns.git
synced 2024-12-02 09:27:55 +01:00
Implement request sharing for concurrent requests to the same resource
This commit is contained in:
parent
1bd8870003
commit
9ed331ae3d
@ -30,6 +30,9 @@ class BasicResolver implements Resolver {
|
|||||||
/** @var array */
|
/** @var array */
|
||||||
private $servers = [];
|
private $servers = [];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $pendingQueries = [];
|
||||||
|
|
||||||
public function __construct(Cache $cache = null, ConfigLoader $configLoader = null) {
|
public function __construct(Cache $cache = null, ConfigLoader $configLoader = null) {
|
||||||
$this->cache = $cache ?? new ArrayCache;
|
$this->cache = $cache ?? new ArrayCache;
|
||||||
$this->configLoader = $configLoader ?? \stripos(PHP_OS, "win") === 0
|
$this->configLoader = $configLoader ?? \stripos(PHP_OS, "win") === 0
|
||||||
@ -134,7 +137,11 @@ class BasicResolver implements Resolver {
|
|||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
public function query(string $name, int $type): Promise {
|
public function query(string $name, int $type): Promise {
|
||||||
return call(function () use ($name, $type) {
|
if (isset($this->pendingQueries[$type . " " . $name])) {
|
||||||
|
return $this->pendingQueries[$type . " " . $name];
|
||||||
|
}
|
||||||
|
|
||||||
|
$promise = call(function () use ($name, $type) {
|
||||||
if (!$this->config) {
|
if (!$this->config) {
|
||||||
$this->config = yield $this->configLoader->loadConfig();
|
$this->config = yield $this->configLoader->loadConfig();
|
||||||
}
|
}
|
||||||
@ -209,6 +216,13 @@ class BasicResolver implements Resolver {
|
|||||||
|
|
||||||
throw new ResolutionException("No response from any nameserver after {$attempts} attempts");
|
throw new ResolutionException("No response from any nameserver after {$attempts} attempts");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->pendingQueries[$type . " " . $name] = $promise;
|
||||||
|
$promise->onResolve(function () use ($name, $type) {
|
||||||
|
unset($this->pendingQueries[$type . " " . $name]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +38,20 @@ class IntegrationTest extends TestCase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that two concurrent requests to the same resource share the same request and do not result in two requests
|
||||||
|
* being sent.
|
||||||
|
*/
|
||||||
|
public function testRequestSharing() {
|
||||||
|
Loop::run(function () {
|
||||||
|
$promise1 = Dns\query("example.com", Record::A);
|
||||||
|
$promise2 = Dns\query("example.com", Record::A);
|
||||||
|
|
||||||
|
$this->assertSame($promise1, $promise2);
|
||||||
|
$this->assertSame(yield $promise1, yield $promise2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function provideHostnames() {
|
public function provideHostnames() {
|
||||||
return [
|
return [
|
||||||
["google.com"],
|
["google.com"],
|
||||||
|
Loading…
Reference in New Issue
Block a user