Coder Social home page Coder Social logo

dns's People

Contributors

austinheap avatar ayesh avatar azjezz avatar bilge avatar brzuchal avatar bwoebi avatar carusogabriel avatar cctjl avatar danack avatar danog avatar daverandom avatar estshy avatar guuzen avatar imbrish avatar kelunik avatar peleg avatar peter279k avatar psafarov avatar rdlowrey avatar sasezaki avatar staabm avatar trowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dns's Issues

Default nameservers without port

If google's public DNS servers on Windows is used following error occurs:

Fatal error: Uncaught exception 'Amp\Dns\ResolutionException' with message 'Connection to udp://8.8.8.8 failed: [Error #0] Failed to parse address "8.8.8.8"'

The default nameservers setting:

"nameservers" => [
    "8.8.8.8",
    "8.8.4.4",
],

A correction could be setting port value:

"nameservers" => [
    "8.8.8.8:53",
    "8.8.4.4:53",
],

Optional setting is optional

My life would be eased if it were possible to set the following options on Addr\Client after instantiation and not require them in the constructor:

  • $socketAddr
  • $socketPort
  • $requestTimeout

Instances can function perfectly well with default values. More importantly, though, the Client class is generally going to be a dependency of other classes and so must be injected. By allowing at least $requestTimeout to be modified after instantiation the classes that are composed of Client instances can expose the option to modify DNS resolution timeouts.

I realize that clients currently open a UDP connection at instantiation time and hold that for the life of the object. As a result, allowing the address values to be modified would add some logic to the current code.

Amazon MySql db connection issue

I am connecting to an amazon DB from windows php 7.2.4 with following code:
https://gist.github.com/plankes-projects/d941f49bf74353f0b29700261192c639

I get DNS timeout exception when I am running it on my windows developer machine.
https://gist.github.com/plankes-projects/c3cfd2a6aead806adc7a9efaf545ba48

Everthing works fine if I am using this config with eloquent or if I am connecting to a local DB:
https://gist.github.com/plankes-projects/afbe1d66eb08262a0f1484cf9fbaf402

Following amphp versions are installed with composer:
amphp/amp dev-master 9b2fb76 A non-blocking concurrency framework for PHP applications.
amphp/byte-stream v1.3.1 A stream abstraction to make working with non-blocking I/O...
amphp/cache v1.2.0 A promise-aware caching API for Amp.
amphp/dns v0.9.12 Async DNS resolution for Amp.
amphp/file v0.3.1 Allows non-blocking access to the filesystem for Amp.
amphp/mysql dev-master aec58f4 Asynchronous parallel Mysql client built on the Amp concur...
amphp/parallel v0.2.5 Parallel processing component for Amp.
amphp/parser v1.0.0 A generator parser to make streaming parsers simple.
amphp/process v0.3.3 Asynchronous process manager.
amphp/socket v0.10.8 Async socket connection / server tools for Amp.
amphp/sync v1.0.1 Mutex, Semaphore, and other synchronization tools for Amp.
amphp/uri v0.1.3 Uri Parser and Resolver.
amphp/windows-registry v0.3.1 Windows Registry Reader.

Moved from amphp/mysql#67

Setting for default timeout

Currently we allow default timeouts on Linux via /etc/resolv.conf. On Windows there's no such thing we support. It would be cool to have a global setting for the timeout I think that can be set on Windows.

Relates to kelunik/acme-client#44.

Watch resolv.conf for changes

I think we should watch /etc/resolv.conf for changes or alternatively cache the config only for a certain amount of time.

Possible infinite loop

From reading the source at

dns/lib/DefaultResolver.php

Lines 170 to 176 in 55de45b

// Get the next available request ID
do {
$requestId = $this->requestIdCounter++;
if ($this->requestIdCounter >= MAX_REQUEST_ID) {
$this->requestIdCounter = 1;
}
} while (isset($this->pendingRequests[$requestId]));
it seems like this might run into an infinite loop, once MAX_REQUEST_ID requests have been lost due to UDP being used?

CreateProcess failed, error 193

Hi!
OS: Windows 10 Pro 18362
PHP Version: 7.3.8 Thread Safe

I'm sorry but I cannot give you a lot of infos since the program I'm using wasn't made by me, the person who made it is @danog and the program is MadelineProto

Full output:

#0 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/process/lib/Process.php(108): Amp\Process\Internal\Windows\Runner->start('reg query "HKEY...', '', Array, Array)
#1 [internal function]: Amp\Process\Process->Amp\Process\{closure}()
#2 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#3 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#4 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/process/lib/Process.php(110): Amp\call(Object(Closure))
#5 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(65): Amp\Process\Process->start()
#6 [internal function]: Amp\WindowsRegistry\WindowsRegistry->Amp\WindowsRegistry\{closure}()
#7 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#8 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#9 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(75): Amp\call(Object(Closure))
#10 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(21): Amp\WindowsRegistry\WindowsRegistry->query('HKEY_LOCAL_MACH...')
#11 [internal function]: Amp\WindowsRegistry\WindowsRegistry->Amp\WindowsRegistry\{closure}()
#12 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#13 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#14 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(38): Amp\call(Object(Closure))
#15 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/WindowsConfigLoader.php(32): Amp\WindowsRegistry\WindowsRegistry->read('HKEY_LOCAL_MACH...')
#16 [internal function]: Amp\Dns\WindowsConfigLoader->Amp\Dns\{closure}()
#17 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#18 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#19 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/WindowsConfigLoader.php(82): Amp\call(Object(Closure))
#20 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/Rfc1035StubResolver.php(217): Amp\Dns\WindowsConfigLoader->loadConfig()
#21 [internal function]: Amp\Dns\Rfc1035StubResolver->Amp\Dns\{closure}()
#22 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#23 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#24 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/Rfc1035StubResolver.php(219): Amp\call(Object(Closure))
#25 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(189): Amp\Dns\Rfc1035StubResolver->reloadConfig()
#26 [internal function]: Amp\DoH\Rfc8484StubResolver->Amp\DoH\{closure}()
#27 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#28 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#29 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(191): Amp\call(Object(Closure))
#30 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(75): Amp\DoH\Rfc8484StubResolver->reloadConfig()
#31 [internal function]: Amp\DoH\Rfc8484StubResolver->Amp\DoH\{closure}()
#32 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#33 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#34 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(172): Amp\call(Object(Closure))
#35 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/DataCenter.php(246): Amp\DoH\Rfc8484StubResolver->resolve('my.telegram.org', NULL)
#36 [internal function]: danog\MadelineProto\DataCenter->danog\MadelineProto\{closure}()
#37 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#38 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#39 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/DataCenter.php(336): Amp\call(Object(Closure))
#40 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/DataCenter.php(564): danog\MadelineProto\DataCenter->socketConnect(Object(danog\MadelineProto\Stream\ConnectionContext), 'tcp://my.telegr...', Object(Amp\Socket\ClientConnectContext), Object(Amp\Artax\Internal\CombinedCancellationToken))
#41 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/Transport/DefaultStream.php(63): danog\MadelineProto\DataCenter->danog\MadelineProto\{closure}('tcp://my.telegr...', Object(Amp\Socket\ClientConnectContext), Object(Amp\Artax\Internal\CombinedCancellationToken))
#42 [internal function]: danog\MadelineProto\Stream\Transport\DefaultStream->connectAsync(Object(danog\MadelineProto\Stream\ConnectionContext), '')
#43 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#44 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(256): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#45 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/Async/Stream.php(38): danog\MadelineProto\Stream\Transport\DefaultStream::call(Object(Generator))
#46 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/ConnectionContext.php(361): danog\MadelineProto\Stream\Transport\DefaultStream->connect(Object(danog\MadelineProto\Stream\ConnectionContext), '')
#47 [internal function]: danog\MadelineProto\Stream\ConnectionContext->getStream('')
#48 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#49 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(113): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#50 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(256): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#51 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/Async/Stream.php(38): danog\MadelineProto\Stream\Common\BufferedRawStream::call(Object(Generator))
#52 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/ConnectionContext.php(361): danog\MadelineProto\Stream\Common\BufferedRawStream->connect(Object(danog\MadelineProto\Stream\ConnectionContext), '')
#53 [internal function]: danog\MadelineProto\Stream\ConnectionContext->getStream()
#54 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#55 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(113): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#56 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(256): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#57 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/ProxySocketPool.php(132): danog\MadelineProto\ProxySocketPool::call(Object(Generator))
#58 [internal function]: danog\MadelineProto\ProxySocketPool->danog\MadelineProto\{closure}()
#59 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#60 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#61 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/ProxySocketPool.php(155): Amp\call(Object(Closure))
#62 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/ProxySocketPool.php(104): danog\MadelineProto\ProxySocketPool->checkoutNewSocket('tcp://my.telegr...', Object(Amp\Artax\Internal\CombinedCancellationToken))
#63 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/HttpSocketPool.php(78): danog\MadelineProto\ProxySocketPool->checkout('tcp://my.telegr...', Object(Amp\Artax\Internal\CombinedCancellationToken))
#64 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(420): Amp\Artax\HttpSocketPool->checkout('https://my.tele...', Object(Amp\Artax\Internal\CombinedCancellationToken))
#65 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(202): Amp\Artax\DefaultClient->doWrite(Object(Amp\Artax\Internal\RequestCycle))
#66 [internal function]: Amp\Artax\DefaultClient->Amp\Artax\{closure}()
#67 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#68 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#69 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(91): Amp\call(Object(Closure))
#70 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(206): Amp\asyncCall(Object(Closure))
#71 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(116): Amp\Artax\DefaultClient->doRequest(Object(Amp\Artax\Request), Object(Amp\Uri\Uri), Array, NULL, Object(Amp\NullCancellationToken))
#72 [internal function]: Amp\Artax\DefaultClient->Amp\Artax\{closure}()
#73 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(105): Generator->send(21)
#74 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Success.php(36): Amp\Coroutine->Amp\{closure}(NULL, Array)
#75 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(138): Amp\Success->onResolve(Object(Closure))
#76 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#77 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(172): Amp\call(Object(Closure))
#78 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/MyTelegramOrgWrapper.php(80): Amp\Artax\DefaultClient->request(Object(Amp\Artax\Request))
#79 [internal function]: danog\MadelineProto\MyTelegramOrgWrapper->login_async('pn')
#80 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#81 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(165): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#82 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Internal/Placeholder.php(130): danog\MadelineProto\Coroutine->danog\MadelineProto\{closure}(NULL, 'pn')
#83 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(156): danog\MadelineProto\Coroutine->resolve('pn')
#84 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Internal/Placeholder.php(130): danog\MadelineProto\Coroutine->danog\MadelineProto\{closure}(NULL, 'pn\r\n')
#85 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Deferred.php(45): class@anonymous->resolve('pn\r\n')
#86 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/byte-stream/lib/ResourceInputStream.php(107): Amp\Deferred->resolve('pn\r\n')
#87 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Loop/Driver.php(116): Amp\ByteStream\ResourceInputStream::Amp\ByteStream\{closure}('n', 'pn\r\n')
#88 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Loop/Driver.php(72): Amp\Loop\Driver->tick()
#89 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Loop.php(84): Amp\Loop\Driver->run()
#90 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(199): Amp\Loop::run(Object(Closure))
#91 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/APIFactory.php(147): danog\MadelineProto\APIFactory::wait(Object(danog\MadelineProto\Coroutine))
#92 C:\Users\Knocks\OneDrive\Programming\Bot\Loggerbot\bot.php(37): danog\MadelineProto\APIFactory->__call('loop', Array)
#93 {main}
DataCenter:             Connection failed: Amp\Process\ProcessException: Could not start process Errno: 2; proc_open(): CreateProcess failed, error code - 193 in phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/process/lib/Internal/Windows/Runner.php:92
Stack trace:
#0 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/process/lib/Process.php(108): Amp\Process\Internal\Windows\Runner->start('reg query "HKEY...', '', Array, Array)
#1 [internal function]: Amp\Process\Process->Amp\Process\{closure}()
#2 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#3 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#4 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/process/lib/Process.php(110): Amp\call(Object(Closure))
#5 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(65): Amp\Process\Process->start()
#6 [internal function]: Amp\WindowsRegistry\WindowsRegistry->Amp\WindowsRegistry\{closure}()
#7 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#8 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#9 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(75): Amp\call(Object(Closure))
#10 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(21): Amp\WindowsRegistry\WindowsRegistry->query('HKEY_LOCAL_MACH...')
#11 [internal function]: Amp\WindowsRegistry\WindowsRegistry->Amp\WindowsRegistry\{closure}()
#12 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#13 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#14 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/windows-registry/lib/WindowsRegistry.php(38): Amp\call(Object(Closure))
#15 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/WindowsConfigLoader.php(32): Amp\WindowsRegistry\WindowsRegistry->read('HKEY_LOCAL_MACH...')
#16 [internal function]: Amp\Dns\WindowsConfigLoader->Amp\Dns\{closure}()
#17 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#18 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#19 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/WindowsConfigLoader.php(82): Amp\call(Object(Closure))
#20 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/Rfc1035StubResolver.php(217): Amp\Dns\WindowsConfigLoader->loadConfig()
#21 [internal function]: Amp\Dns\Rfc1035StubResolver->Amp\Dns\{closure}()
#22 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#23 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#24 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/dns/lib/Rfc1035StubResolver.php(219): Amp\call(Object(Closure))
#25 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(189): Amp\Dns\Rfc1035StubResolver->reloadConfig()
#26 [internal function]: Amp\DoH\Rfc8484StubResolver->Amp\DoH\{closure}()
#27 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#28 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#29 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(191): Amp\call(Object(Closure))
#30 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(75): Amp\DoH\Rfc8484StubResolver->reloadConfig()
#31 [internal function]: Amp\DoH\Rfc8484StubResolver->Amp\DoH\{closure}()
#32 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#33 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#34 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/dns-over-https/lib/Rfc8484StubResolver.php(172): Amp\call(Object(Closure))
#35 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/DataCenter.php(246): Amp\DoH\Rfc8484StubResolver->resolve('my.telegram.org', NULL)
#36 [internal function]: danog\MadelineProto\DataCenter->danog\MadelineProto\{closure}()
#37 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#38 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#39 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/DataCenter.php(336): Amp\call(Object(Closure))
#40 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/DataCenter.php(564): danog\MadelineProto\DataCenter->socketConnect(Object(danog\MadelineProto\Stream\ConnectionContext), 'tcp://my.telegr...', Object(Amp\Socket\ClientConnectContext), Object(Amp\Artax\Internal\CombinedCancellationToken))
#41 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/Transport/DefaultStream.php(63): danog\MadelineProto\DataCenter->danog\MadelineProto\{closure}('tcp://my.telegr...', Object(Amp\Socket\ClientConnectContext), Object(Amp\Artax\Internal\CombinedCancellationToken))
#42 [internal function]: danog\MadelineProto\Stream\Transport\DefaultStream->connectAsync(Object(danog\MadelineProto\Stream\ConnectionContext), '')
#43 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#44 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(256): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#45 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/Async/Stream.php(38): danog\MadelineProto\Stream\Transport\DefaultStream::call(Object(Generator))
#46 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/ConnectionContext.php(361): danog\MadelineProto\Stream\Transport\DefaultStream->connect(Object(danog\MadelineProto\Stream\ConnectionContext), '')
#47 [internal function]: danog\MadelineProto\Stream\ConnectionContext->getStream('')
#48 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#49 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(113): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#50 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(256): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#51 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/Async/Stream.php(38): danog\MadelineProto\Stream\Common\BufferedRawStream::call(Object(Generator))
#52 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Stream/ConnectionContext.php(361): danog\MadelineProto\Stream\Common\BufferedRawStream->connect(Object(danog\MadelineProto\Stream\ConnectionContext), '')
#53 [internal function]: danog\MadelineProto\Stream\ConnectionContext->getStream()
#54 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#55 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(165): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#56 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Failure.php(29): danog\MadelineProto\Coroutine->danog\MadelineProto\{closure}(Object(Amp\Process\ProcessException), NULL)
#57 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Internal/Placeholder.php(38): Amp\Failure->onResolve(Object(Closure))
#58 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(182): danog\MadelineProto\Coroutine->onResolve(Object(Closure))
#59 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(256): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#60 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/ProxySocketPool.php(132): danog\MadelineProto\ProxySocketPool::call(Object(Generator))
#61 [internal function]: danog\MadelineProto\ProxySocketPool->danog\MadelineProto\{closure}()
#62 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#63 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#64 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/ProxySocketPool.php(155): Amp\call(Object(Closure))
#65 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/ProxySocketPool.php(104): danog\MadelineProto\ProxySocketPool->checkoutNewSocket('tcp://my.telegr...', Object(Amp\Artax\Internal\CombinedCancellationToken))
#66 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/HttpSocketPool.php(78): danog\MadelineProto\ProxySocketPool->checkout('tcp://my.telegr...', Object(Amp\Artax\Internal\CombinedCancellationToken))
#67 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(420): Amp\Artax\HttpSocketPool->checkout('https://my.tele...', Object(Amp\Artax\Internal\CombinedCancellationToken))
#68 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(202): Amp\Artax\DefaultClient->doWrite(Object(Amp\Artax\Internal\RequestCycle))
#69 [internal function]: Amp\Artax\DefaultClient->Amp\Artax\{closure}()
#70 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(60): Generator->current()
#71 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#72 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(91): Amp\call(Object(Closure))
#73 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(206): Amp\asyncCall(Object(Closure))
#74 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(116): Amp\Artax\DefaultClient->doRequest(Object(Amp\Artax\Request), Object(Amp\Uri\Uri), Array, NULL, Object(Amp\NullCancellationToken))
#75 [internal function]: Amp\Artax\DefaultClient->Amp\Artax\{closure}()
#76 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(105): Generator->send(21)
#77 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Success.php(36): Amp\Coroutine->Amp\{closure}(NULL, Array)
#78 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Coroutine.php(138): Amp\Success->onResolve(Object(Closure))
#79 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/functions.php(66): Amp\Coroutine->__construct(Object(Generator))
#80 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/artax/lib/DefaultClient.php(172): Amp\call(Object(Closure))
#81 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/MyTelegramOrgWrapper.php(80): Amp\Artax\DefaultClient->request(Object(Amp\Artax\Request))
#82 [internal function]: danog\MadelineProto\MyTelegramOrgWrapper->login_async('pn')
#83 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(95): Generator->current()
#84 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(165): danog\MadelineProto\Coroutine->__construct(Object(Generator))
#85 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Internal/Placeholder.php(130): danog\MadelineProto\Coroutine->danog\MadelineProto\{closure}(NULL, 'pn')
#86 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Coroutine.php(156): danog\MadelineProto\Coroutine->resolve('pn')
#87 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Internal/Placeholder.php(130): danog\MadelineProto\Coroutine->danog\MadelineProto\{closure}(NULL, 'pn\r\n')
#88 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Deferred.php(45): class@anonymous->resolve('pn\r\n')
#89 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/byte-stream/lib/ResourceInputStream.php(107): Amp\Deferred->resolve('pn\r\n')
#90 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Loop/Driver.php(116): Amp\ByteStream\ResourceInputStream::Amp\ByteStream\{closure}('n', 'pn\r\n')
#91 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Loop/Driver.php(72): Amp\Loop\Driver->tick()
#92 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/amphp/amp/lib/Loop.php(84): Amp\Loop\Driver->run()
#93 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/Tools.php(199): Amp\Loop::run(Object(Closure))
#94 phar://C:/Users/Knocks/OneDrive/Programming/Bot/Loggerbot/madeline.phar/vendor/danog/madelineproto/src/danog/MadelineProto/APIFactory.php(147): danog\MadelineProto\APIFactory::wait(Object(danog\MadelineProto\Coroutine))
#95 C:\Users\Knocks\OneDrive\Programming\Bot\Loggerbot\bot.php(37): danog\MadelineProto\APIFactory->__call('loop', Array)
#96 {main}

Update promise on CNAME following

Just like Artax uses promise updates when following redirects, amphp/dns should update the promises when following CNAME records and similar things.

fwrite can fail

The fwrite here can fail, generating a notice but continues to run in a presumably bogus state.

So I guess the code so check the return value.....and possibly suppress the warning? (shakes fist at PHP's 'error' model)

Exception:

Notice: fwrite(): send of 32 bytes failed with errno=65 No route to host in /documents/projects/github/FlickrArtaxService/vendor/daverandom/addr/lib/Addr/Client.php on line 182
Call Stack
#   Time    Memory  Function    Location
1   0.0000  231824  {main}( )   ../index.php:0
2   0.0012  392856  showFlickrStatus( ) ../index.php:31
3   0.0026  498496  FlickrService\FlickrAPI\flickrTestLogin->execute( ) ../flickrBootstrap.php:65
4   0.0032  527960  FlickrService\FlickrAPI\FlickrAPI->callAPI( )   ../flickrTestLogin.php:141
5   0.0052  774976  Artax\Client->request( )    ../FlickrAPI.php:42
6   0.0052  778120  Alert\NativeReactor->tick( )    ../Client.php:53
7   0.0052  778800  Alert\NativeReactor->executeAlarms( )   ../NativeReactor.php:82
8   0.0052  778984  Alert\NativeReactor->doAlarmCallback( ) ../NativeReactor.php:122
9   0.0052  778640  Artax\Client->Artax\{closure}( )    ../NativeReactor.php:143
10  0.0052  778688  Artax\AsyncClient->request( )   ../Client.php:49
11  0.0055  802840  Artax\AsyncClient->resolveDns( )    ../AsyncClient.php:87
12  0.0055  804320  Artax\AddrDnsResolver->resolve( )   ../AsyncClient.php:354
13  0.0055  805152  Addr\Resolver->resolve( )   ../AddrDnsResolver.php:51
14  0.0068  819912  Addr\Resolver->resolveFromServer( ) ../Resolver.php:176
15  0.0068  820008  Addr\Client->resolve( ) ../Resolver.php:151
16  0.0068  821848  Addr\Client->processPendingLookup( )    ../Client.php:342
17  0.0068  825632  Addr\Client->sendRequest( ) ../Client.php:305
18  0.0076  887512  fwrite ( )  ../Client.php:182

Cyclic reference with loop, resolver will never be destructed

As long as the gcWatcher is not cancelled, the BasicResolver will never be destroyed as the watcher contains a reference to the resolver which is retained by the loop. The loop driver will also never be destroyed as long it has watchers. Watcher callbacks have references to the loop and the loop has references to the watchers (or events). But this is something different.

Nicer handling of PTR queries

amphp DNS doesn't handle calls like this:

yield Amp\Dns\resolve('209.141.56.29', $options = ['types' => Amp\Dns\Record::PTR])

Currently, you need to manually convert the IP address to the right PTR query:

yield Amp\Dns\resolve('29.56.141.209.in-addr.arpa', $options = ['types' => Amp\Dns\Record::PTR])

The legacy Net_DNS library has some code to handle PTR queries correctly, when the input looks like an IP address:

        /*
         * If the name looks like an IP address then do an appropriate
         * PTR query.
         */
        if (preg_match('/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/', $name, $regs)) {
            $name = $regs[4].'.'.$regs[3].'.'.$regs[2].'.'.$regs[1].'.in-addr.arpa.';
            $type = 'PTR';
        }

https://github.com/pear/Net_DNS/blob/5786b8c6f21c3cc8915fe251dac1571fa524a417/Net/DNS/Resolver.php#L552-L559

It would be nice for amphp to do this too.

Implement server pool

Implement the ability to fail over to other servers and/or query multiple servers at once.

Good queries failing with "Response decode error" when running multiple requests in parallel via Amp\any - Fine when running in series

Consider this simple test script:

<?php
require __DIR__.'/../vendor/autoload.php';

function format_exception(Exception $ex, $indent = 0) {
  $output = get_class($ex).' - '.$ex->getMessage();
  if ($ex instanceof Amp\CombinatorException) {
    foreach ($ex->getExceptions() as $inner) {
      $output .= "\n".str_repeat('  ', $indent). ' --> '.format_exception($inner, $indent + 1);
    }
  } else {
    $prev = $ex->getPrevious();
    if ($prev) {
      $output .= "\n".str_repeat('  ', $indent). ' --> '.format_exception($prev, $indent + 1);
    }
  }
  return $output;
}

const IPS_TO_LOAD = 2;

Amp\run(function () {
  $start_ip = '209.141.56.29';
  $start_ip_raw = ip2long($start_ip);

  for (
    $current_ip_raw = $start_ip_raw - IPS_TO_LOAD;
    $current_ip_raw < $start_ip_raw + IPS_TO_LOAD;
    $current_ip_raw++
  ) {
    $current_ip = long2ip($current_ip_raw);
    $ips[] = $current_ip;
    $lookups[$current_ip] = Amp\Dns\query($current_ip, Amp\Dns\Record::PTR);
  }

  list($failed, $succeeded) = (yield Amp\any($lookups));
  echo '**** ', count($failed), " failures! ****\n\n";
  foreach ($ips as $ip) {
    if (array_key_exists($ip, $succeeded)) {
      list(list($result)) = $succeeded[$ip];
      echo $ip, ': ', $result, "\n";
    } else if (array_key_exists($ip, $failed)) {
      $ex = $failed[$ip];
      if ($ex instanceof Amp\Dns\NoRecordException) {
        echo $ip, ": No reverse DNS\n";
      } else {
        echo $ip, ': EXCEPTION: ', format_exception($ex), "\n";
      }
    } else {
      echo $ip, ": UNKNOWN\n";
    }
  }
});

It sends 5 PTR lookups concurrently for a range of IP addresses. I'm seeing this fail sporadically, with different requests failing every time I run it. All failures are listed as "Decode error: Empty domain name at position 0x38"

Example output:

**** 2 failures! ****

209.141.56.27: buyvm.lamphost.cn
209.141.56.28: EXCEPTION: Amp\Dns\ResolutionException - All name resolution requests failed
 --> Amp\CombinatorException - All promises passed to Amp\some() failed
   --> Amp\Dns\ResolutionException - Response decode error
     --> UnexpectedValueException - Decode error: Empty domain name at position 0x38
209.141.56.29: dan.cx
209.141.56.30: EXCEPTION: Amp\Dns\ResolutionException - All name resolution requests failed
 --> Amp\CombinatorException - All promises passed to Amp\some() failed
   --> Amp\Dns\ResolutionException - Response decode error
     --> UnexpectedValueException - Decode error: Empty domain name at position 0x38

Tests fail with OPCache enabled

Quite a few tests fail with OPCache enabled, because Socket::ask yields an empty array instead of an instance of Message.

Remove amphp/file dependency

I'm only using amphp/socket and there is following dependency tree that is useless to me:
amphp/socker -> amphp/file -> amphp/sync, amphp/parallel

So after removing this dependency, my consumers will have to install 3 packages less.

Additionally, replacing it with bytestream increases performance almost 10x!

Index: bench/HostLoaderBench.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- bench/HostLoaderBench.php	(date 1545833204000)
+++ bench/HostLoaderBench.php	(date 1545833204000)
@@ -0,0 +1,17 @@
+<?php
+
+namespace Amp\Dns\Bench;
+
+use Amp\Dns\HostLoader;
+use Amp\Loop;
+
+class HostLoaderBench
+{
+    public function benchHostLoader()
+    {
+        Loop::run(function () {
+            $loader = new HostLoader(__DIR__ . "/../test/data/hosts");
+            yield $loader->loadHosts();
+        });
+    }
+}
Index: lib/HostLoader.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- lib/HostLoader.php	(revision 836b0896b0105298373669754ece8ad8577c0854)
+++ lib/HostLoader.php	(date 1545834232000)
@@ -2,6 +2,7 @@
 
 namespace Amp\Dns;
 
+use Amp\ByteStream\ResourceInputStream;
 use Amp\File;
 use Amp\Promise;
 use Amp\Uri\InvalidDnsNameException;
@@ -26,7 +27,8 @@
             $data = [];
 
             try {
-                $contents = yield File\get($this->path);
+                $resource = new ResourceInputStream(fopen($this->path, 'r'), filesize($this->path));
+                $contents = yield $resource->read();
             } catch (File\FilesystemException $e) {
                 return [];
             }

Without this change:

benchHostLoader               I99 P0 	[ฮผ Mo]/r: 404.861 400.640 (ฮผs) 	[ฮผSD ฮผRSD]/r: 16.964ฮผs 4.19%

1 subjects, 100 iterations, 100 revs, 0 rejects, 0 failures, 0 warnings
(best [mean mode] worst) = 376.960 [404.861 400.640] 490.050 (ฮผs)
โ…€T: 40,486.090ฮผs ฮผSD/r 16.964ฮผs ฮผRSD/r: 4.190%

With this change:

benchHostLoader               I99 P0 	[ฮผ Mo]/r: 46.553 44.866 (ฮผs) 	[ฮผSD ฮผRSD]/r: 2.447ฮผs 5.26%

1 subjects, 100 iterations, 100 revs, 0 rejects, 0 failures, 0 warnings
(best [mean mode] worst) = 43.520 [46.553 44.866] 54.270 (ฮผs)
โ…€T: 4,655.250ฮผs ฮผSD/r 2.447ฮผs ฮผRSD/r: 5.257%

Google Fallback

Currently we fallback to Google's public DNS servers if we don't have a config. This affected probably only Windows, as we don't have /etc/resolv.conf there. On other systems, that could only happen if there is an error reading /etc/resolv.conf.

I don't like sending all DNS queries silently as a fallback to Google. If the system config can't be read, it's either a weird system not yet supported (a bug then), or something other that has to be fixed on the system. @DaveRandom mentioned he'd like to keep the fallback, as we can still continue resolving domain names, but would like to issue a warning when the default config is used.

#40 plans to deprecate the default config and I plan to remove default nameservers when we release a new major version based on Amp v2.

Please add a ๐Ÿ‘ if you want to drop the fallback, add a ๐Ÿ‘Ž if you want to keep the fallback.

Improve failure tolerance

Currently we always use the first nameserver only. If that one fails, it should retry with the next server.

Timeout not working

I've discovered the timeout mechanism isn't working. In some tests, the reactor will run forever, but most of the time the test will take about ~1 minute. The timeout value seems to be ignored. I've stepped through with xdebug, but it gets lost and i can't seem to identify the issue. Example:

$promise = \Amp\Dns\resolve('www.google.ca', ['timeout' => 100, 'server' => 'tcp://8.8.8.0:53', 
  'types' => Record::A, 'cache' => false ]);

try {
    $result = \Amp\wait($promise);
    $this->fail("Resolve did not timeout when expected {$result}");
} catch (\Exception $e) {
    $this->assertInstanceOf(\Exception::class, $e);
}

I've tried with and without ev extension. I've tried with regular IP, udp scheme, smaller/larger values, cache on/off.

This is with php version 5.5.30. and amphp/dns 0.8.10

Any ideas or recommendations to get this working?

amphp/dns/lib/DefaultResolver.php(632): Undefined offset: x

There seems to be a bug in amphp/dns v0.8.15. I'm getting Undefined offset errors in DefaultResolver

/amphp/dns/lib/DefaultResolver.php line 632, method processDecodedResponse:

private function processDecodedResponse($serverId, $requestId, $response) {
        list($promisor, $name, $type, $uri, $timeout) = $this->pendingRequests[$requestId];
        //...
}

$this->pendingRequests doesn't contain a value at index $requestId

Stacktrace:

#1 vendor/amphp/dns/lib/DefaultResolver.php(632): Xel\Cake\Error\AppConsoleErrorHandler->Xel\Cake\Error\{closure}(8, Undefined offset: 13, vendor/amphp/dns/lib/DefaultResolver.php, 632, array)
#2 vendor/amphp/dns/lib/DefaultResolver.php(622): Amp\Dns\DefaultResolver->processDecodedResponse(557, 13, LibDNS\Messages\Message)
#3 vendor/amphp/dns/lib/DefaultResolver.php(597): Amp\Dns\DefaultResolver->decodeResponsePacket(string, string)
#4 vendor/amphp/amp/lib/NativeReactor.php(265): Amp\Dns\DefaultResolver->onReadable(0000000032606eb2000000000d168e0f, resource, null)
#5 vendor/amphp/amp/lib/NativeReactor.php(249): Amp\NativeReactor->doIoCallback(0000000032606eb2000000000d168e0f, stdClass, resource)
#6 vendor/amphp/amp/lib/NativeReactor.php(214): Amp\NativeReactor->selectActionableStreams(0)
#7 vendor/amphp/amp/lib/NativeReactor.php(71): Amp\NativeReactor->doTick(false)
#8 vendor/amphp/amp/lib/functions.php(46): Amp\NativeReactor->run(Closure)

The call is coming from DefaultResolver->query(), which is called in our case from the library kelunik/acme Dns01->verifyChallenge()

Incomplete packet error

Next Amp\Dns\DnsException: All query attempts failed for mozilla.cloudflare-dns.com: Unexpected error during resolution: Decode error: Incomplete packet (tried to read 12 bytes from index 0, Unexpected error during resolution: Decode error: Incomplete packet (tried to read 12 bytes from index 0 in /home/shishcat1/redacted/vendor/amphp/dns/lib/Rfc1035StubResolver.php:193
Stack trace:
#0 [internal function]: Amp\Dns\Rfc1035StubResolver->Amp\Dns{closure}()
PHP 7.4.2 debian

Missing check whether IP version is right on resolve

Calling resolve with an IP address currently simply resolves to chat address. But it doesn't check whether it's allowed by the current "types" in $options:

var_dump(yield Amp\Dns\resolve('8.8.8.8', ['types' => Amp\Dns\Record::AAAA])); works just fine, but should result in an exception, because no records found. Or for the A โ†’ AAAA case, we can rewrite it to an IPv6 address.

isValidHostname throws exception on valid hostnames

https://github.com/amphp/dns/blame/master/lib/DefaultResolver.php#L87

2.0.0.127.b.barracudacentral.org is a prefectly valid hostname that doesn't match the regex.

Suggest instead:

$pattern = "/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$/i";

It appears the top answer on stackoverflow is wrong: http://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address

Improve Windows configuration loader

From kelunik/acme-client#64 (comment):

The issue is in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces. Check NameServer and DhcpNameServer properties in all subkeys and remove or correct the ones which are wrong. The first one found will win, no matter if its available or not.

I think vendor\amphp\dns\lib\DefaultResolver.php#loadResolvConf function should check if the nameserver is available before using it. Or find a better way in windows to get the correct nameserver because the interfaces in this subkey where not consistent with the the interfaces listed elsewhere, also windows itself did not use this nameserver found by this function.

Subtype 'Too many redirects' DnsException

throw new DnsException("Giving up resolution of '{$searchName}', too many redirects");

It would be very nice to differentiate this type of error. In my situation this difference is important as other DnsException throws are usually temporary, so the script can be rerun successfully whereas 'Too many redirections' error tend to be permanent (e.g. if there is a cyclic aliasing)

Are dotless domains valid?

Didn't find any test that states dotless domains are invalid.
Are they valid?
If yes - then there is a bug, because resolve method throws exception for dotless domains.
If no - maybe test (and probably explicit exception message) that states dotless domains are invalid should be introduced for clarity and stability?

My use case is simple docker development environment where i want to be able to access hosts in same network by containers/services names. They are usually dotless.

DNS frequently fails on Windows

A little over 50% of the time, a async CLI application fails to start on Windows because the DNS doesn't work. Once it works, the problem does not seem to occur again, but there's a high probability it will fail unrecoverably at each process start. The operation is retried 5 times and the same error continues to occur until a new PHP process is started, when the dice is re-rolled to see if DNS is actually going to work. It doesn't matter if a process successfully ran a few seconds ago, all rolls are independent and have an equal chance of failing, despite recent successful resolutions by another process.

In BasicResolver.php line 149:

[Amp\Dns\DnsException]
All query attempts failed for example.com: Reading from the server failed, Reading from the server failed

amphp/dns v0.9.15

"Could not find a nameserver in the Windows Registry" out-of-the-box on Windows

I'm hitting this exception when trying to use this library:

Fatal error:  Uncaught exception 'Amp\Dns\ResolutionException' with message 'Could not find a nameserver in the Windows Registry.' in C:\src\dnstools.ws\vendor\amphp\dns\lib\DefaultResolver.php:383
Stack trace:
#0 [internal function]: Amp\Dns\DefaultResolver::loadResolvConf()
#1 C:\src\dnstools.ws\vendor\amphp\amp\lib\functions.php(874): Generator-&gt;throw(Object(Amp\WindowsRegistry\KeyNotFoundException))
#2 [internal function]: Amp\__coroutineSend(Object(Amp\WindowsRegistry\KeyNotFoundException), NULL, Object(Amp\CoroutineState))
#3 C:\src\dnstools.ws\vendor\amphp\amp\lib\Placeholder.php(91): call_user_func('Amp\\__coroutine...', Object(Amp\WindowsRegistry\KeyNotFoundException), NULL, Object(Amp\CoroutineState))
#4 C:\src\dnstools.ws\vendor\amphp\amp\lib\PrivatePromisor.php(20): Amp\PrivatePlaceholder-&gt;resolve(Object(Amp\WindowsRegistry\KeyNotFoundException), NULL)
#5 [internal function]: Amp\PrivatePlaceholder-&gt;Amp\{closure}(Object(Amp\WindowsRegistry\KeyNotFoundException), NULL)
#6 C:\src\dnstools.ws\vendor\amphp\amp\lib\ in C:\src\dnstools.ws\vendor\amphp\dns\lib\DefaultResolver.php on line 383

Looking at

dns/lib/DefaultResolver.php

Lines 353 to 372 in 8659b56

$keys = [
"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\NameServer",
"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\DhcpNameServer",
];
$reader = new WindowsRegistry;
$nameserver = "";
while ($nameserver === "" && ($key = array_shift($keys))) {
try {
$nameserver = (yield $reader->read($key));
} catch (KeyNotFoundException $e) { }
}
if ($nameserver === "") {
$subKeys = (yield $reader->listKeys("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"));
while ($nameserver === "" && ($key = array_shift($subKeys))) {
try {
$nameserver = (yield $reader->read("{$key}\\NameServer"));
, it looks like the code looks for these keys:

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{guid}\NameServer

However, on my computer, the DNS server is at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{55de6892-f5b0-4632-aeb8-d34874155c77}\DhcpNameServer.

Instead of just looking at Interfaces\{guid}\NameServer, I think it should also look for Interfaces\{guid}\DchpNameServer.

I'm on Windows 10, using DHCP.

Random nameserver failures at start of program on Windows

This problem typically only manifests itself when the program is first run, and occurs intermittently (not guaranteed to be reproducible). In my test output (sorry about formatting), I initiate two requests that fail immediately with DNS errors and never complete. Then, a third request is sent that completes successfully. All three requests are made to the same address (http://example.com). A further 50 requests are made to the same address that complete without error; only the first two (initiated at the same time, at the beginning) fail.

[2018-03-25 11:36:37] Async.DEBUG: Importing app #5206 (1/53)...
[2018-03-25 11:36:37] Async.DEBUG: Importing app #5207 (2/53)...
[2018-03-25 11:36:37] Async.ERROR: REQ 5206: Amp\Dns\ConfigException: At least one nameserver is required for a valid config in amphp\dns\lib\Config.php:13 Stack trace: #0 amphp\dns\lib\WindowsConfigLoader.php(78): Amp\Dns\Config->__construct(Array, Array) #1 [internal function]: Amp\Dns\WindowsConfigLoader->Amp\Dns\{closure}() #2 amphp\amp\lib\Coroutine.php(74): Generator->send(Array) #3 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Array) #4 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Array) #5 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #6 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve('# Copyright (c)...') #7 amphp\amp\lib\Internal\ResolutionQueue.php(51): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #8 amphp\amp\lib\Success.php(33): Amp\Internal\ResolutionQueue->__invoke(NULL, '# Copyright (c)...') #9 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Success->onResolve(Object(Amp\Internal\ResolutionQueue)) #10 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Success)) #11 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #12 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #13 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #14 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #15 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, 'dobe.com\r\n127.0...') #16 amphp\amp\lib\Deferred.php(41): class@anonymous->resolve('dobe.com\r\n127.0...') #17 amphp\byte-stream\lib\ResourceInputStream.php(100): Amp\Deferred->resolve('dobe.com\r\n127.0...') #18 amphp\amp\lib\Loop\Driver.php(112): Amp\ByteStream\ResourceInputStream::Amp\ByteStream\{closure}('bf', 'dobe.com\r\n127.0...') #19 amphp\amp\lib\Loop\Driver.php(70): Amp\Loop\Driver->tick() #20 amphp\amp\lib\Loop.php(76): Amp\Loop\Driver->run() #21 src\Import\ImportAsync.php(45): Amp\Loop::run(Object(Closure)) #22 src\Import\ImportAsyncCommand.php(26): ScriptFUSION\Steam250\Import\ImportAsync->import('applist.json') #23 symfony\console\Command\Command.php(252): ScriptFUSION\Steam250\Import\ImportAsyncCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #24 symfony\console\Application.php(946): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #25 symfony\console\Application.php(248): Symfony\Component\Console\Application->doRunCommand(Object(ScriptFUSION\Steam250\Import\ImportAsyncCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #26 symfony\console\Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #27 src\Application.php(31): Symfony\Component\Console\Application->run() #28 bin\250(9): ScriptFUSION\Steam250\Application->start() #29 {main}  Next Amp\Artax\DnsException: Resolving the specified domain failed: 'example.com' in amphp\artax\lib\DefaultClient.php:422 Stack trace: #0 amphp\artax\lib\DefaultClient.php(201): Amp\Artax\DefaultClient->doWrite(Object(Amp\Artax\Internal\RequestCycle)) #1 [internal function]: Amp\Artax\DefaultClient->Amp\Artax\{closure}() #2 amphp\amp\lib\Coroutine.php(71): Generator->throw(Object(Amp\Dns\ConfigException)) #3 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #4 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #5 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #6 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #7 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #8 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #9 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #10 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #11 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #12 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #13 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #14 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #15 amphp\amp\lib\Internal\ResolutionQueue.php(51): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #16 amphp\amp\lib\Failure.php(26): Amp\Internal\ResolutionQueue->__invoke(Object(Amp\Dns\ConfigException), NULL) #17 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Amp\Internal\ResolutionQueue)) #18 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #19 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #20 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #21 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #22 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #23 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #24 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), Array) #25 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Array) #26 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #27 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve('# Copyright (c)...') #28 amphp\amp\lib\Internal\ResolutionQueue.php(51): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #29 amphp\amp\lib\Success.php(33): Amp\Internal\ResolutionQueue->__invoke(NULL, '# Copyright (c)...') #30 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Success->onResolve(Object(Amp\Internal\ResolutionQueue)) #31 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Success)) #32 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #33 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #34 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #35 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #36 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, 'dobe.com\r\n127.0...') #37 amphp\amp\lib\Deferred.php(41): class@anonymous->resolve('dobe.com\r\n127.0...') #38 amphp\byte-stream\lib\ResourceInputStream.php(100): Amp\Deferred->resolve('dobe.com\r\n127.0...') #39 amphp\amp\lib\Loop\Driver.php(112): Amp\ByteStream\ResourceInputStream::Amp\ByteStream\{closure}('bf', 'dobe.com\r\n127.0...') #40 amphp\amp\lib\Loop\Driver.php(70): Amp\Loop\Driver->tick() #41 amphp\amp\lib\Loop.php(76): Amp\Loop\Driver->run() #42 src\Import\ImportAsync.php(45): Amp\Loop::run(Object(Closure)) #43 src\Import\ImportAsyncCommand.php(26): ScriptFUSION\Steam250\Import\ImportAsync->import('applist.json') #44 symfony\console\Command\Command.php(252): ScriptFUSION\Steam250\Import\ImportAsyncCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #45 symfony\console\Application.php(946): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #46 symfony\console\Application.php(248): Symfony\Component\Console\Application->doRunCommand(Object(ScriptFUSION\Steam250\Import\ImportAsyncCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #47 symfony\console\Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #48 src\Application.php(31): Symfony\Component\Console\Application->run() #49 bin\250(9): ScriptFUSION\Steam250\Application->start() #50 {main} [] []
[2018-03-25 11:36:37] Async.ERROR: REQ 5207: Amp\Dns\ConfigException: At least one nameserver is required for a valid config in amphp\dns\lib\Config.php:13 Stack trace: #0 amphp\dns\lib\WindowsConfigLoader.php(78): Amp\Dns\Config->__construct(Array, Array) #1 [internal function]: Amp\Dns\WindowsConfigLoader->Amp\Dns\{closure}() #2 amphp\amp\lib\Coroutine.php(74): Generator->send(Array) #3 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Array) #4 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Array) #5 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #6 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve('# Copyright (c)...') #7 amphp\amp\lib\Internal\ResolutionQueue.php(51): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #8 amphp\amp\lib\Success.php(33): Amp\Internal\ResolutionQueue->__invoke(NULL, '# Copyright (c)...') #9 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Success->onResolve(Object(Amp\Internal\ResolutionQueue)) #10 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Success)) #11 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #12 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #13 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #14 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #15 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, 'dobe.com\r\n127.0...') #16 amphp\amp\lib\Deferred.php(41): class@anonymous->resolve('dobe.com\r\n127.0...') #17 amphp\byte-stream\lib\ResourceInputStream.php(100): Amp\Deferred->resolve('dobe.com\r\n127.0...') #18 amphp\amp\lib\Loop\Driver.php(112): Amp\ByteStream\ResourceInputStream::Amp\ByteStream\{closure}('bf', 'dobe.com\r\n127.0...') #19 amphp\amp\lib\Loop\Driver.php(70): Amp\Loop\Driver->tick() #20 amphp\amp\lib\Loop.php(76): Amp\Loop\Driver->run() #21 src\Import\ImportAsync.php(45): Amp\Loop::run(Object(Closure)) #22 src\Import\ImportAsyncCommand.php(26): ScriptFUSION\Steam250\Import\ImportAsync->import('applist.json') #23 symfony\console\Command\Command.php(252): ScriptFUSION\Steam250\Import\ImportAsyncCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #24 symfony\console\Application.php(946): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #25 symfony\console\Application.php(248): Symfony\Component\Console\Application->doRunCommand(Object(ScriptFUSION\Steam250\Import\ImportAsyncCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #26 symfony\console\Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #27 src\Application.php(31): Symfony\Component\Console\Application->run() #28 bin\250(9): ScriptFUSION\Steam250\Application->start() #29 {main}  Next Amp\Artax\DnsException: Resolving the specified domain failed: 'example.com' in amphp\artax\lib\DefaultClient.php:422 Stack trace: #0 amphp\artax\lib\DefaultClient.php(201): Amp\Artax\DefaultClient->doWrite(Object(Amp\Artax\Internal\RequestCycle)) #1 [internal function]: Amp\Artax\DefaultClient->Amp\Artax\{closure}() #2 amphp\amp\lib\Coroutine.php(71): Generator->throw(Object(Amp\Dns\ConfigException)) #3 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #4 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #5 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #6 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #7 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #8 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #9 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #10 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #11 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #12 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #13 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #14 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #15 amphp\amp\lib\Internal\ResolutionQueue.php(51): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #16 amphp\amp\lib\Failure.php(26): Amp\Internal\ResolutionQueue->__invoke(Object(Amp\Dns\ConfigException), NULL) #17 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Amp\Internal\ResolutionQueue)) #18 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #19 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #20 amphp\amp\lib\Failure.php(26): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), NULL) #21 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Failure->onResolve(Object(Closure)) #22 amphp\amp\lib\Internal\Placeholder.php(151): Amp\Coroutine->resolve(Object(Amp\Failure)) #23 amphp\amp\lib\Coroutine.php(93): Amp\Coroutine->fail(Object(Amp\Dns\ConfigException)) #24 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(Object(Amp\Dns\ConfigException), Array) #25 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Array) #26 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #27 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve('# Copyright (c)...') #28 amphp\amp\lib\Internal\ResolutionQueue.php(51): Amp\Coroutine->Amp\{closure}(NULL, '# Copyright (c)...') #29 amphp\amp\lib\Success.php(33): Amp\Internal\ResolutionQueue->__invoke(NULL, '# Copyright (c)...') #30 amphp\amp\lib\Internal\Placeholder.php(122): Amp\Success->onResolve(Object(Amp\Internal\ResolutionQueue)) #31 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Success)) #32 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #33 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #34 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #35 amphp\amp\lib\Coroutine.php(79): Amp\Coroutine->resolve(Object(Amp\Parallel\Worker\Internal\TaskSuccess)) #36 amphp\amp\lib\Internal\Placeholder.php(127): Amp\Coroutine->Amp\{closure}(NULL, 'dobe.com\r\n127.0...') #37 amphp\amp\lib\Deferred.php(41): class@anonymous->resolve('dobe.com\r\n127.0...') #38 amphp\byte-stream\lib\ResourceInputStream.php(100): Amp\Deferred->resolve('dobe.com\r\n127.0...') #39 amphp\amp\lib\Loop\Driver.php(112): Amp\ByteStream\ResourceInputStream::Amp\ByteStream\{closure}('bf', 'dobe.com\r\n127.0...') #40 amphp\amp\lib\Loop\Driver.php(70): Amp\Loop\Driver->tick() #41 amphp\amp\lib\Loop.php(76): Amp\Loop\Driver->run() #42 src\Import\ImportAsync.php(45): Amp\Loop::run(Object(Closure)) #43 src\Import\ImportAsyncCommand.php(26): ScriptFUSION\Steam250\Import\ImportAsync->import('applist.json') #44 symfony\console\Command\Command.php(252): ScriptFUSION\Steam250\Import\ImportAsyncCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #45 symfony\console\Application.php(946): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #46 symfony\console\Application.php(248): Symfony\Component\Console\Application->doRunCommand(Object(ScriptFUSION\Steam250\Import\ImportAsyncCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #47 symfony\console\Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #48 src\Application.php(31): Symfony\Component\Console\Application->run() #49 bin\250(9): ScriptFUSION\Steam250\Application->start() #50 {main}
[2018-03-25 11:36:39] Async.DEBUG: Importing app #5208 (3/53)...
[2018-03-25 11:36:39] Async.DEBUG: Completed app #5208 (3/53)...
...

Sometimes, an additional notice is shown.

Notice: Undefined offset: 2 in vendor\amphp\windows-registry\lib\WindowsRegistry.php on line 31

Call Stack:
    0.0010     353968   1. {main}() bin\250:0
    0.0270    1491112   2. ScriptFUSION\Steam250\Application->start() bin\250:9
    0.0270    1491112   3. Symfony\Component\Console\Application->run() src\Application.php:31
    0.0610    1804952   4. Symfony\Component\Console\Application->doRun() vendor\symfony\console\Application.php:148
    0.0610    1804952   5. Symfony\Component\Console\Application->doRunCommand() vendor\symfony\console\Application.php:248
    0.0610    1804952   6. Symfony\Component\Console\Command\Command->run() vendor\symfony\console\Application.php:946
    0.0610    1810224   7. ScriptFUSION\Steam250\Import\ImportAsyncCommand->execute() vendor\symfony\console\Command\Command.php:252
    0.0810    2552648   8. ScriptFUSION\Steam250\Import\ImportAsync->import() src\Import\ImportAsyncCommand.php:26
    0.1930   34252344   9. Amp\Loop::run() src\Import\ImportAsync.php:45
    0.1940   34263496  10. Amp\Loop\Driver->run() vendor\amphp\amp\lib\Loop.php:76
    0.3100   35574336  11. Amp\Loop\Driver->tick() vendor\amphp\amp\lib\Loop\Driver.php:70
    0.3100   35573960  12. Amp\Loop\NativeDriver->dispatch() vendor\amphp\amp\lib\Loop\Driver.php:130
    0.3100   35573960  13. Amp\Loop\NativeDriver->selectStreams() vendor\amphp\amp\lib\Loop\NativeDriver.php:68
    0.3110   35574464  14. Amp\Process\Internal\Windows\SocketConnector->onReadableExitCode() vendor\amphp\amp\lib\Loop\NativeDriver.php:172
    0.3110   35574936  15. Amp\Deferred->resolve() vendor\amphp\process\lib\Internal\Windows\SocketConnector.php:297
    0.3110   35574936  16. {anonymous-class:vendor\amphp\amp\lib\Deferred.php:18-23}->resolve() vendor\amphp\amp\lib\Deferred.php:41
    0.3110   35581272  17. Amp\Coroutine->Amp\{closure}() vendor\amphp\amp\lib\Internal\Placeholder.php:127
    0.3140   35552936  18. Amp\Coroutine->resolve() vendor\amphp\amp\lib\Coroutine.php:79
    0.3140   35560664  19. Amp\Coroutine->Amp\{closure}() vendor\amphp\amp\lib\Internal\Placeholder.php:127
    0.3140   35560664  20. Generator->send() vendor\amphp\amp\lib\Coroutine.php:74
    0.3140   35560664  21. Amp\WindowsRegistry\WindowsRegistry->Amp\WindowsRegistry\{closure}() vendor\amphp\amp\lib\Coroutine.php:74

Invalid promise resolution for cached failures

We currently cache in case of no results for a maximum of 5 minutes. The first invocation results in a ResolutionException (should actually be NoRecordException, see #25). All later invocations result in an successfully resolved promise yielding an empty array. Instead there should be the same outcome as for non-cached DNS requests (the same exception).

API Refactoring

With v0.8.8 we introduced classes as resolvers: v0.8.7...v0.8.8

We should modify the API to drop the nameserver options from Amp\Dns\query and Amp\Dns\resolve. If anyone needs a different resolver, they should just go ahead and create a new resolver object with the nameserver as argument and execute their query then.

BasicResolver configLoader parameter

Hello :)

There's an issue with the setting of the configLoader in the BasicResolver constructor where incorrect precedence means the constructor always assigns a WindowsConfigLoader if you try to supply your own.

PR #61 fixes this

Support for RES_OPTIONS

We should add support for the RES_OPTIONS environment variable. The way it works is described in the resolv.conf man page.

DNS resolution failed -- possibly cache bug

We get an Amp\Dns\ResolutionException with the message

"DNS resolution failed: www.google.com"

These are the last couple of lines from our stack-trace:

#0 ...\vendor\amphp\dns\lib\Client.php(298): Amp\Dns\Client->completePendingLookup(0, NULL, 3)
#1 ...\vendor\amphp\dns\lib\Client.php(220): Amp\Dns\Client->completeRequest(Array, NULL, 3)
#2 ...\vendor\amphp\amp\lib\NativeReactor.php(184): Amp\Dns\Client->Amp\Dns\{closure}(Object(Amp\NativeReactor), 2)
#3 ...\vendor\amphp\amp\lib\NativeReactor.php(123): Amp\NativeReactor->executeAlarms()

It seems that the problem originates in lib/Client.php on line 311 where $cacheHit is true but $addr is NULL. Google is reachable by DNS from the environment in question.

zend_mm_heap corrupted on centos guest

Repo script is below. It's basically example 2 with an extra host name inserted.

The environment is Centos 6.4 with self-built version of PHP 5.6.2. It is sitting inside a vagrant box hosted on Mac OSX .

The hostname is being resolved by a hosts file on the host, not the guest. I'm going to attempt to capture the packets being sent between guest/host.

The output is

# php 002_async.php 
github.com => 192.30.252.131
google.com => 62.24.157.49
FAILED: imagick.test
stackoverflow.com => 198.252.206.140
localhost => 127.0.0.1
192.168.0.1 => 192.168.0.1
::1 => ::1
zend_mm_heap corrupted
<?php

require __DIR__ . '/../vendor/autoload.php';

Amp\run(function() {
    $names = [
        'github.com',
        'google.com',
        'imagick.test', // this is the extra domain
        'stackoverflow.com',
        'localhost',
        '192.168.0.1',
        '::1',
    ];

    $promises = [];
    $resolver = new Amp\Dns\Resolver;
    foreach ($names as $name) {
        $promise = $resolver->resolve($name);
        $promises[$name] = $promise;
    }

    // Combine our multiple promises into a single promise
    $comboPromise = Amp\some($promises);

    // Yield control until the combo promise resolves
    list($errors, $successes) = (yield $comboPromise);

    foreach ($names as $name) {
        echo isset($errors[$name]) ? "FAILED: {$name}\n" : "{$name} => {$successes[$name][0]}\n";
    }

    // Stop the event loop so we don't sit around forever
    Amp\stop();
});

DNS timeout causes array out of bounds error.

It looks like when a DNS lookup times out, the code doesn't handle it gracefully. i.e. when

$this->completePendingLookup($id, null, ResolutionErrors::ERR_SERVER_TIMEOUT);

is called, it causes an out of bounds error in AddrDnsResolver.php on line 49:

Error message: "Undefined offset: 3" aka ERR_SERVER_TIMEOUT

Stack trace:

intahwebz/vendor/rdlowrey/artax/src/Artax/AddrDnsResolver.php:49
intahwebz/vendor/daverandom/addr/lib/Addr/Client.php:267
intahwebz/vendor/daverandom/addr/lib/Addr/Client.php:188
intahwebz/vendor/rdlowrey/alert/lib/NativeReactor.php:143
intahwebz/vendor/rdlowrey/alert/lib/NativeReactor.php:122
intahwebz/vendor/rdlowrey/alert/lib/NativeReactor.php:82
intahwebz/vendor/rdlowrey/artax/src/Artax/Client.php:53
intahwebz/src/BaseReality/Service/FlickrArtax.php:33

Reset state / Accessor

It must be possible to reset the state. If you want to start your unit tests with a clean reactor, DNS won't work in when used in multiple tests, because the server is still loaded but doesn't receive any watcher events anymore, because the old reactor where the watchers where registered, doesn't exist anymore.

Additionally, it's currently not possible to mock DNS.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.