diff --git a/CHANGELOG.md b/CHANGELOG.md index 8acfa413..fb1aed29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ cos-php-sdk-v5 Upgrade Guide ==================== +2.1.2 to 2.1.3 +---------- +- Add `download` interface, which is used for concurrent block download. +- Add callback of `upload` and `download` progress +- Fix request retry + 2.1.1 to 2.1.2 ---------- - The interface supports custom parameters diff --git a/sample/cosClient.php b/sample/cosClient.php new file mode 100644 index 00000000..e5f7ba21 --- /dev/null +++ b/sample/cosClient.php @@ -0,0 +1,29 @@ + $region, //园区 + 'schema' => 'https', //协议头部,默认为http + 'timeout' => 10, //超时时间 + 'connect_timeout' => 10, //连接超时时间 + 'ip' => '', //ip + 'port' => '', //端口 + 'endpoint' => '', //endpoint + 'domain' => '', //自定义域名 + 'proxy' => '', //代理服务器 + 'retry' => 10, //重试次数 + 'userAgent' => '', //UA + 'credentials'=> array( + 'secretId' => $secretId , + 'secretKey' => $secretKey, + 'token' => $token, + 'anonymous' => true, //匿名模式 + ) + ) +); diff --git a/sample/download.php b/sample/download.php new file mode 100644 index 00000000..4471cc25 --- /dev/null +++ b/sample/download.php @@ -0,0 +1,37 @@ + $region, + 'schema' => 'https', //协议头部,默认为http + 'credentials'=> array( + 'secretId' => $secretId , + 'secretKey' => $secretKey))); +$local_path = "/data/exampleobject"; + +$printbar = function($totolSize, $downloadedSize) { + printf("downloaded [%d/%d]\n", $downloadedSize, $totolSize); +}; + +try { + $result = $cosClient->download( + $bucket = 'examplebucket-125000000', //格式:BucketName-APPID + $key = 'exampleobject', + $saveAs = local_path, + $options=['Progress'=>$printbar, //指定进度条 + 'PartSize' => 10 * 1024 * 1024, //分块大小 + 'Concurrency' => 5 //并发数 + ] + ); + // 请求成功 + print_r($result); +} catch (\Exception $e) { + // 请求失败 + echo($e); +} + diff --git a/sample/upload.php b/sample/upload.php index 70a24a29..c55bfd8c 100644 --- a/sample/upload.php +++ b/sample/upload.php @@ -13,6 +13,11 @@ 'secretId' => $secretId , 'secretKey' => $secretKey))); $local_path = "/data/exampleobject"; + +$printbar = function($totolSize, $uploadedSize) { + printf("uploaded [%d/%d]\n", $uploadedSize, $totolSize); +}; + try { $result = $cosClient->upload( $bucket = 'examplebucket-125000000', //格式:BucketName-APPID @@ -36,7 +41,10 @@ ), 'ContentMD5' => 'string', 'ServerSideEncryption' => 'string', - 'StorageClass' => 'string' + 'StorageClass' => 'string', //存储类型 + 'Progress'=>$printbar, //指定进度条 + 'PartSize' => 10 * 1024 * 1024, //分块大小 + 'Concurrency' => 5 //并发数 ) */ ); diff --git a/src/Qcloud/Cos/Client.php b/src/Qcloud/Cos/Client.php index 6218390a..a4de6e4a 100644 --- a/src/Qcloud/Cos/Client.php +++ b/src/Qcloud/Cos/Client.php @@ -12,8 +12,10 @@ use GuzzleHttp\Command\Guzzle\Description; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Deserializer; +use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Command\CommandInterface; use GuzzleHttp\Command\Exception\CommandException; +use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Middleware; use GuzzleHttp\Psr7; @@ -75,7 +77,7 @@ * @method object SelectObjectContent (array $arg) */ class Client extends GuzzleClient { - const VERSION = '2.1.2'; + const VERSION = '2.1.3'; public $httpClient; @@ -110,6 +112,7 @@ public function __construct($cosConfig) { $service = Service::getService(); $handler = HandlerStack::create(); + $handler->push(Middleware::retry($this->retryDecide(), $this->retryDelay())); $handler->push(Middleware::mapRequest(function (RequestInterface $request) { return $request->withHeader('User-Agent', $this->cosConfig['userAgent']); })); @@ -135,6 +138,38 @@ public function __construct($cosConfig) { 'commandToRequestTransformer'], [$this, 'responseToResultTransformer'], null); } + public function retryDecide() { + return function ( + $retries, + RequestInterface $request, + ResponseInterface $response = null, + \Exception $exception = null + ) { + if ($retries >= $this->cosConfig['retry']) { + return false; + } + if ($response != null && $response->getStatusCode() >= 400 ) { + return true; + } + if ($exception instanceof \Qcloud\Cos\Exception\ServiceResponseException) { + if ($exception->getStatusCode() >= 400) { + return true; + } + } + + if ($exception instanceof ConnectException) { + return true; + } + + return false; + }; + } + + public function retryDelay() { + return function ($numberOfRetries) { + return 1000 * $numberOfRetries; + }; + } public function commandToRequestTransformer(CommandInterface $command) { $this->action = $command->GetName(); @@ -168,21 +203,15 @@ public function __destruct() { } public function __call($method, array $args) { - for ($i = 0; $i <= $this->cosConfig['retry']; $i++) { - try { - $rt = parent::__call(ucfirst($method), $args); - return $rt; - } catch (\Exception $e) { - if ($i != $this->cosConfig['retry']) { - sleep(1 << ($i)); - continue; - } - $previous = $e->getPrevious(); - if ($previous !== null) { - throw $previous; - } else { - throw $e; - } + try { + $rt = parent::__call(ucfirst($method), $args); + return $rt; + } catch (\Exception $e) { + $previous = $e->getPrevious(); + if ($previous !== null) { + throw $previous; + } else { + throw $e; } } } diff --git a/src/Qcloud/Cos/MultipartUpload.php b/src/Qcloud/Cos/MultipartUpload.php index e594df11..e38ddd40 100644 --- a/src/Qcloud/Cos/MultipartUpload.php +++ b/src/Qcloud/Cos/MultipartUpload.php @@ -112,6 +112,7 @@ public function uploadParts($uploadId) { 'rejected' => function ($reason, $index) { printf("part [%d] upload failed, reason: %s\n", $index, $reason); + throw($reason); } ]); $promise = $pool->promise();