mirror of
https://github.com/danog/dns.git
synced 2024-11-30 04:29:06 +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 */
|
||||
private $servers = [];
|
||||
|
||||
/** @var array */
|
||||
private $pendingQueries = [];
|
||||
|
||||
public function __construct(Cache $cache = null, ConfigLoader $configLoader = null) {
|
||||
$this->cache = $cache ?? new ArrayCache;
|
||||
$this->configLoader = $configLoader ?? \stripos(PHP_OS, "win") === 0
|
||||
@ -134,7 +137,11 @@ class BasicResolver implements Resolver {
|
||||
|
||||
/** @inheritdoc */
|
||||
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) {
|
||||
$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");
|
||||
});
|
||||
|
||||
$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() {
|
||||
return [
|
||||
["google.com"],
|
||||
|
Loading…
Reference in New Issue
Block a user