Skip to content

Commit 1037fc3

Browse files
committed
[Dns] Handle timeouts in Executor
1 parent b3f8578 commit 1037fc3

File tree

5 files changed

+34
-15
lines changed

5 files changed

+34
-15
lines changed

Query/CachedExecutor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function __construct(ExecutorInterface $executor, RecordCache $cache)
1616
$this->cache = $cache;
1717
}
1818

19-
public function query($nameserver, Query $query, $callback)
19+
public function query($nameserver, Query $query, $callback, $errorback)
2020
{
2121
$cachedRecords = $this->cache->lookup($query);
2222
if (count($cachedRecords)) {
@@ -29,7 +29,7 @@ public function query($nameserver, Query $query, $callback)
2929
$this->executor->query($nameserver, $query, function ($response) use ($cache, $query, $callback) {
3030
$callback($response);
3131
$cache->storeResponseMessage($query->currentTime, $response);
32-
});
32+
}, $errorback);
3333
}
3434

3535
private function buildResponse(Query $query, array $cachedRecords)

Query/Executor.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,24 @@ class Executor implements ExecutorInterface
1515
private $loop;
1616
private $parser;
1717
private $dumper;
18+
private $timeout;
1819

19-
public function __construct(LoopInterface $loop, Parser $parser, BinaryDumper $dumper)
20+
public function __construct(LoopInterface $loop, Parser $parser, BinaryDumper $dumper, $timeout = 5)
2021
{
2122
$this->loop = $loop;
2223
$this->parser = $parser;
2324
$this->dumper = $dumper;
25+
$this->timeout = $timeout;
2426
}
2527

26-
public function query($nameserver, Query $query, $callback)
28+
public function query($nameserver, Query $query, $callback, $errorback)
2729
{
2830
$request = $this->prepareRequest($query);
2931

3032
$queryData = $this->dumper->toBinary($request);
3133
$transport = strlen($queryData) > 512 ? 'tcp' : 'udp';
3234

33-
$this->doQuery($nameserver, $transport, $queryData, $callback);
35+
$this->doQuery($nameserver, $transport, $queryData, $callback, $errorback);
3436
}
3537

3638
public function prepareRequest(Query $query)
@@ -44,25 +46,33 @@ public function prepareRequest(Query $query)
4446
return $request;
4547
}
4648

47-
public function doQuery($nameserver, $transport, $queryData, $callback)
49+
public function doQuery($nameserver, $transport, $queryData, $callback, $errorback)
4850
{
4951
$that = $this;
5052
$parser = $this->parser;
53+
$loop = $this->loop;
5154

5255
$response = new Message();
5356

54-
$retryWithTcp = function () use ($that, $nameserver, $queryData, $callback) {
55-
$that->doQuery($nameserver, 'tcp', $queryData, $callback);
57+
$retryWithTcp = function () use ($that, $nameserver, $queryData, $callback, $errorback) {
58+
$that->doQuery($nameserver, 'tcp', $queryData, $callback, $errorback);
5659
};
5760

61+
$timer = $this->loop->addTimer($this->timeout, function () use (&$conn, $errorback) {
62+
$conn->close();
63+
$errorback(new TimeoutException("query timed out"));
64+
});
65+
5866
$conn = $this->createConnection($nameserver, $transport);
59-
$conn->on('data', function ($data) use ($that, $retryWithTcp, $conn, $parser, $response, $transport, $callback) {
67+
$conn->on('data', function ($data) use ($that, $retryWithTcp, $conn, $parser, $response, $transport, $callback, $loop, $timer) {
6068
$responseReady = $parser->parseChunk($data, $response);
6169

6270
if (!$responseReady) {
6371
return;
6472
}
6573

74+
$loop->cancelTimer($timer);
75+
6676
if ($response->header->isTruncated()) {
6777
if ('tcp' === $transport) {
6878
throw new BadServerException('The server set the truncated bit although we issued a TCP request');

Query/ExecutorInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
interface ExecutorInterface
66
{
7-
public function query($nameserver, Query $query, $callback);
7+
public function query($nameserver, Query $query, $callback, $errorback);
88
}

Query/TimeoutException.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace React\Dns\Query;
4+
5+
class TimeoutException extends \Exception
6+
{
7+
}

Resolver/Resolver.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,21 @@ public function resolve($domain, $callback, $errback = null)
2727
{
2828
$that = $this;
2929

30+
if (!$errback) {
31+
$errback = function ($error) {
32+
throw $error;
33+
};
34+
}
35+
3036
$query = new Query($domain, Message::TYPE_A, Message::CLASS_IN, time());
3137

3238
$this->executor->query($this->nameserver, $query, function (Message $response) use ($that, $callback, $errback) {
3339
try {
3440
$that->extractAddress($response, Message::TYPE_A, $callback);
3541
} catch (RecordNotFoundException $e) {
36-
if (!$errback) {
37-
throw $e;
38-
}
39-
4042
$errback($e);
4143
}
42-
});
44+
}, $errback);
4345
}
4446

4547
public function extractAddress(Message $response, $type, $callback)

0 commit comments

Comments
 (0)