Example #1
0
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return $this->chatClient->postReply($command, 'Mhm, I need a film title you want me to look for.');
     }
     $search = $command->getText();
     $message = (yield $this->chatClient->postMessage($command->getRoom(), sprintf('_Looking for \'%s\' for you…_', $search)));
     $params = $this->buildTitleSearchParams($search);
     // Send it out.
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request(sprintf('%s?%s', self::OMDB_API_ENDPOINT, http_build_query($params))));
     /** @var \stdClass $data */
     $data = @json_decode($response->getBody());
     if (!$data || $data->Response === 'False') {
         return $this->chatClient->postMessage($command->getRoom(), 'I couldn\'t find anything for that title.');
     }
     $searchResults = [];
     foreach ($data->Search as $searchResult) {
         $searchResults[$searchResult->imdbID] = $searchResult;
     }
     // Only pick the top 3 results if needed.
     $searchResults = array_slice($searchResults, 0, 3, true);
     /** @var PostedMessage $chatMessage */
     (yield $this->chatClient->editMessage($message, $this->formatSearchResults($searchResults)));
     $requests = [];
     // Send out multiple http requests to get film descriptions and ratings.
     foreach ($searchResults as $id => $searchResult) {
         $requests[$id] = sprintf('%s?%s', self::OMDB_API_ENDPOINT, http_build_query($this->buildTitleDescParams($id)));
     }
     // Wait until all requests are done, allow failures.
     $allRequests = \Amp\some($this->httpClient->requestMulti($requests));
     list($errors, $responses) = (yield $allRequests);
     $descriptionResults = [];
     foreach ($responses as $key => $response) {
         $responseBody = @json_decode($response->getBody());
         if (!$responseBody || $responseBody->Response === 'False') {
             continue;
         }
         $descriptionResults[$key] = $responseBody;
     }
     return $this->chatClient->editMessage($message, $this->formatSearchResults($searchResults, $descriptionResults));
 }
Example #2
0
function __doResolve($name, array $types, $options)
{
    static $state;
    $state = $state ?: (yield \Amp\resolve(__init()));
    if (empty($types)) {
        (yield new CoroutineResult([]));
        return;
    }
    assert(array_reduce($types, function ($result, $val) {
        return $result && \is_int($val);
    }, true), 'The $types passed to DNS functions must all be integers (from \\Amp\\Dns\\Record class)');
    $name = \strtolower($name);
    $result = [];
    // Check for cache hits
    if (!isset($options["cache"]) || $options["cache"]) {
        foreach ($types as $k => $type) {
            $cacheKey = "{$name}#{$type}";
            $cacheValue = (yield $state->arrayCache->get($cacheKey));
            if ($cacheValue !== null) {
                $result[$type] = $cacheValue;
                unset($types[$k]);
            }
        }
        if (empty($types)) {
            (yield new CoroutineResult($result));
            return;
        }
    }
    $timeout = empty($options["timeout"]) ? $state->config["timeout"] : (int) $options["timeout"];
    if (empty($options["server"])) {
        if (empty($state->config["nameservers"])) {
            throw new ResolutionException("No nameserver specified in system config");
        }
        $uri = "udp://" . $state->config["nameservers"][0];
    } else {
        $uri = __parseCustomServerUri($options["server"]);
    }
    foreach ($types as $type) {
        $promises[] = __doRequest($state, $uri, $name, $type);
    }
    try {
        list(, $resultArr) = (yield \Amp\timeout(\Amp\some($promises), $timeout));
        foreach ($resultArr as $value) {
            $result += $value;
        }
    } catch (\Amp\TimeoutException $e) {
        if (substr($uri, 0, 6) == "tcp://") {
            throw new TimeoutException("Name resolution timed out for {$name}");
        } else {
            $options["server"] = \preg_replace("#[a-z.]+://#", "tcp://", $uri);
            (yield new CoroutineResult(\Amp\resolve(__doResolve($name, $types, $options))));
        }
    } catch (ResolutionException $e) {
        if (empty($result)) {
            // if we have no cached results
            throw $e;
        }
    } catch (\RuntimeException $e) {
        // if all promises in Amp\some fail
        if (empty($result)) {
            // if we have no cached results
            throw new ResolutionException("All name resolution requests failed", 0, $e);
        }
    }
    (yield new CoroutineResult($result));
}
Example #3
0
<?php

require __DIR__ . '/../vendor/autoload.php';
/**
 * Note that Client::requestMulti() is nothing more than a convenience wrapper
 * to prevent us from having to call Client::request() several times and store
 * the resulting promises in an array ourselves. Doing so would have the exact
 * same effect and all requests would be executed in parallel either way.
 */
$promises = (new Amp\Artax\Client())->requestMulti(['google' => 'http://www.google.com', 'news' => 'http://news.google.com', 'bing' => 'http://www.bing.com', 'yahoo' => 'https://www.yahoo.com']);
// Tolerate errors in some of the requests. If any one of the promises in our array
// succeeds then the result is a two-item array of errors and successes. If *none*
// of our response promises succeed then this line will throw.
$comboPromise = Amp\some($promises);
list($errors, $responses) = Amp\wait($comboPromise);
// Alternatively we could use the following line to require all of our responses to succeed. If
// any one of the response promises resolves as a failure then this line will throw:
$comboPromise = Amp\all($promises);
$responses = Amp\wait($comboPromise);
// Now, let's iterate over the responses to demonstrate that they retain the same keys from
// our original call to Amp\Artax\Client::request():
foreach ($responses as $key => $response) {
    printf("%s | HTTP/%s %d %s\n", $key, $response->getProtocol(), $response->getStatus(), $response->getReason());
}