使用Pool时如何修复GuzzleHttp \ Exception \ ServerException?

时间:2015-09-28 19:22:43

标签: php guzzle

The docs说我可以创建一个池,任何失败的请求都应该调用“被拒绝”的方法,但我得到的是{ 'account_id': '1', 'item_id' : 'cce3d2a017f6f1870ce8480a32506bed', 'item_name' : 'CE', 'item_quantity' : '1', 'item_price' : '1' } 。这是我的代码:

GuzzleHttp\Exception\ServerException

以下是例外:

$client = new GuzzleHttp\Client([
    'base_uri' => ServerConfig::Json('file_server'),
]);

$requests = function() use ($client, $delete_time) {
    foreach($this->pcs_master->pcs as $id => $pcs) {
        $paths = $pcs->database->SelectSimpleArray('wopi_doc', 'wd_filepath', ['wd_deleted_at IS NOT NULL', 'wd_deleted_at < ?' => $delete_time]);

        if ($paths) {
            foreach (array_chunk($paths, self::WOPI_SOFT_DELETE_CHUNK_SIZE) as $chunk) {
                yield $client->delete('/', [
                    'body' => json_encode(['paths' => $files]),
                ]);
            }
        }
    }
};

$pool = new GuzzleHttp\Pool($client, $requests(), [
    'concurrency' => self::WOPI_SOFT_DELETE_MAX_CONCURRENT_REQUESTS,
    'fulfilled' => function ($response, $index) {
        dump('fulfilled', $response, $index);
    },
    'rejected' => function ($reason, $index) {
        dump('rejected', $reason, $index);
    },
]);

$pool->promise()->wait();

看起来TYPE: GuzzleHttp\Exception\ServerException MESSAGE: Server error: 500 FILE: /path/to/my/project/vendor/guzzlehttp/guzzle/src/Middleware.php(68) === TRACE === #0 /path/to/my/project/vendor/guzzlehttp/promises/src/Promise.php(199): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response)) #1 /path/to/my/project/vendor/guzzlehttp/promises/src/Promise.php(152): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), Array) #2 /path/to/my/project/vendor/guzzlehttp/promises/src/TaskQueue.php(60): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}() #3 /path/to/my/project/vendor/guzzlehttp/promises/src/Promise.php(240): GuzzleHttp\Promise\TaskQueue->run(true) #4 /path/to/my/project/vendor/guzzlehttp/promises/src/Promise.php(217): GuzzleHttp\Promise\Promise->invokeWaitFn() #5 /path/to/my/project/vendor/guzzlehttp/promises/src/Promise.php(261): GuzzleHttp\Promise\Promise->waitIfPending() #6 /path/to/my/project/vendor/guzzlehttp/promises/src/Promise.php(219): GuzzleHttp\Promise\Promise->invokeWaitList() #7 /path/to/my/project/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending() #8 /path/to/my/project/vendor/guzzlehttp/guzzle/src/Client.php(129): GuzzleHttp\Promise\Promise->wait() #9 /path/to/my/project/vendor/guzzlehttp/guzzle/src/Client.php(87): GuzzleHttp\Client->request('delete', '/', Array) #10 /path/to/my/project/class/crondaemon.php(5057): GuzzleHttp\Client->__call('delete', Array) #11 /path/to/my/project/class/crondaemon.php(5057): GuzzleHttp\Client->delete('/', Array) #12 /path/to/my/project/vendor/guzzlehttp/guzzle/src/Pool.php(55): CronDaemon::{closure}() #13 [internal function]: GuzzleHttp\Pool::GuzzleHttp\{closure}() #14 /path/to/my/project/vendor/guzzlehttp/promises/src/EachPromise.php(73): Generator->rewind() #15 /path/to/my/project/vendor/guzzlehttp/guzzle/src/Pool.php(74): GuzzleHttp\Promise\EachPromise->promise() #16 /path/to/my/project/class/crondaemon.php(5073): GuzzleHttp\Pool->promise() #17 [internal function]: CronDaemon->DeleteWopiDocs() #18 /path/to/my/project/tests/cron.php(46): call_user_func(Array) #19 /path/to/my/project/tests/cron.php(51): CronDaemonTestScript::main(Array) #20 {main} 行上会抛出异常,但我认为应该创建一个$client->delete对象但是还没有发送它(这是池的工作)?< / p>

2 个答案:

答案 0 :(得分:2)

client::get(), client::put(), client::post(), client::delete()client::request()的抽象,它本身就是client::requestAsync().的抽象。您试图产生一个ResponseInterface实例。 如果您要使用GuzzleHttp\Pool,则必须手动创建Psr\http-message\Request个对象。

yield new GuzzleHttp\Psr7\Request($method, $uri, $headers_array, $body, $protocol_version);

可以通过查看concurrent requestsGuzzleHttp\Psr7\Request

获取更多信息

编辑:回复评论中的问题。 最终,您要发送的每个请求都是使用Client::sendAsync()发送的。这意味着先前在客户端中配置的任何选项在池中使用时都将保持有效。

答案 1 :(得分:-1)

看来我必须出于某种原因将Promise包装在一个函数中:

foreach (array_chunk($paths, self::WOPI_SOFT_DELETE_CHUNK_SIZE) as $chunk) {
    yield function() use ($client, $files) {
        return $client->deleteAsync('/', [
            'body' => json_encode(['paths' => $files]),
        ]);
    };
}