Update core 8.3.0

This commit is contained in:
Rob Davies 2017-04-13 15:53:35 +01:00
parent da7a7918f8
commit cd7a898e66
6144 changed files with 132297 additions and 87747 deletions

View file

@ -1,11 +0,0 @@
phpunit.xml
composer.phar
composer.lock
composer-test.lock
vendor/
build/artifacts/
artifacts/
docs/_build
docs/*.pyc
.idea
.DS_STORE

View file

@ -1,19 +0,0 @@
language: php
php:
- 5.5
- 5.6
- 7.0
- hhvm
sudo: false
install:
- travis_retry composer install --no-interaction --prefer-source
script: make test
matrix:
allow_failures:
- php: hhvm
fast_finish: true

View file

@ -1,31 +1,65 @@
# CHANGELOG
## 1.3.1 - 2016-12-20
### Fixed
- `wait()` foreign promise compatibility
## 1.3.0 - 2016-11-18
### Added
- Adds support for custom task queues.
### Fixed
- Fixed coroutine promise memory leak.
## 1.2.0 - 2016-05-18
* Update to now catch `\Throwable` on PHP 7+
### Changed
- Update to now catch `\Throwable` on PHP 7+
## 1.1.0 - 2016-03-07
* Update EachPromise to prevent recurring on a iterator when advancing, as this
### Changed
- Update EachPromise to prevent recurring on a iterator when advancing, as this
could trigger fatal generator errors.
* Update Promise to allow recursive waiting without unwrapping exceptions.
- Update Promise to allow recursive waiting without unwrapping exceptions.
## 1.0.3 - 2015-10-15
* Update EachPromise to immediately resolve when the underlying promise iterator
### Changed
- Update EachPromise to immediately resolve when the underlying promise iterator
is empty. Previously, such a promise would throw an exception when its `wait`
function was called.
## 1.0.2 - 2015-05-15
* Conditionally require functions.php.
### Changed
- Conditionally require functions.php.
## 1.0.1 - 2015-06-24
* Updating EachPromise to call next on the underlying promise iterator as late
### Changed
- Updating EachPromise to call next on the underlying promise iterator as late
as possible to ensure that generators that generate new requests based on
callbacks are not iterated until after callbacks are invoked.
## 1.0.0 - 2015-05-12
* Initial release
- Initial release

View file

@ -1,4 +1,4 @@
Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
Copyright (c) 2015-2016 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -96,7 +96,7 @@ $promise->resolve('reader.');
## Promise forwarding
Promises can be chained one after the other. Each then in the chain is a new
promise. The return value of of a promise is what's forwarded to the next
promise. The return value of a promise is what's forwarded to the next
promise in the chain. Returning a promise in a `then` callback will cause the
subsequent promises in the chain to only be fulfilled when the returned promise
has been fulfilled. The next promise in the chain will be invoked with the
@ -315,8 +315,11 @@ A promise has the following methods:
- `then(callable $onFulfilled, callable $onRejected) : PromiseInterface`
Creates a new promise that is fulfilled or rejected when the promise is
resolved.
Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.
- `otherwise(callable $onRejected) : PromiseInterface`
Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
- `wait($unwrap = true) : mixed`

View file

@ -1,6 +1,5 @@
{
"name": "guzzlehttp/promises",
"type": "library",
"description": "Guzzle promises library",
"keywords": ["promise"],
"license": "MIT",
@ -15,7 +14,7 @@
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"phpunit/phpunit": "^4.0"
},
"autoload": {
"psr-4": {
@ -23,9 +22,13 @@
},
"files": ["src/functions_include.php"]
},
"scripts": {
"test": "vendor/bin/phpunit",
"test-ci": "vendor/bin/phpunit --coverage-text"
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
"dev-master": "1.4-dev"
}
}
}

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php"
colors="true">
<testsuites>
<testsuite>
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
<exclude>
<directory suffix="Interface.php">src/</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,151 @@
<?php
namespace GuzzleHttp\Promise;
use Exception;
use Generator;
use Throwable;
/**
* Creates a promise that is resolved using a generator that yields values or
* promises (somewhat similar to C#'s async keyword).
*
* When called, the coroutine function will start an instance of the generator
* and returns a promise that is fulfilled with its final yielded value.
*
* Control is returned back to the generator when the yielded promise settles.
* This can lead to less verbose code when doing lots of sequential async calls
* with minimal processing in between.
*
* use GuzzleHttp\Promise;
*
* function createPromise($value) {
* return new Promise\FulfilledPromise($value);
* }
*
* $promise = Promise\coroutine(function () {
* $value = (yield createPromise('a'));
* try {
* $value = (yield createPromise($value . 'b'));
* } catch (\Exception $e) {
* // The promise was rejected.
* }
* yield $value . 'c';
* });
*
* // Outputs "abc"
* $promise->then(function ($v) { echo $v; });
*
* @param callable $generatorFn Generator function to wrap into a promise.
*
* @return Promise
* @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
*/
final class Coroutine implements PromiseInterface
{
/**
* @var PromiseInterface|null
*/
private $currentPromise;
/**
* @var Generator
*/
private $generator;
/**
* @var Promise
*/
private $result;
public function __construct(callable $generatorFn)
{
$this->generator = $generatorFn();
$this->result = new Promise(function () {
while (isset($this->currentPromise)) {
$this->currentPromise->wait();
}
});
$this->nextCoroutine($this->generator->current());
}
public function then(
callable $onFulfilled = null,
callable $onRejected = null
) {
return $this->result->then($onFulfilled, $onRejected);
}
public function otherwise(callable $onRejected)
{
return $this->result->otherwise($onRejected);
}
public function wait($unwrap = true)
{
return $this->result->wait($unwrap);
}
public function getState()
{
return $this->result->getState();
}
public function resolve($value)
{
$this->result->resolve($value);
}
public function reject($reason)
{
$this->result->reject($reason);
}
public function cancel()
{
$this->currentPromise->cancel();
$this->result->cancel();
}
private function nextCoroutine($yielded)
{
$this->currentPromise = promise_for($yielded)
->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
}
/**
* @internal
*/
public function _handleSuccess($value)
{
unset($this->currentPromise);
try {
$next = $this->generator->send($value);
if ($this->generator->valid()) {
$this->nextCoroutine($next);
} else {
$this->result->resolve($value);
}
} catch (Exception $exception) {
$this->result->reject($exception);
} catch (Throwable $throwable) {
$this->result->reject($throwable);
}
}
/**
* @internal
*/
public function _handleFailure($reason)
{
unset($this->currentPromise);
try {
$nextYield = $this->generator->throw(exception_for($reason));
// The throw was caught, so keep iterating on the coroutine
$this->nextCoroutine($nextYield);
} catch (Exception $exception) {
$this->result->reject($exception);
} catch (Throwable $throwable) {
$this->result->reject($throwable);
}
}
}

View file

@ -263,10 +263,17 @@ class Promise implements PromiseInterface
$this->waitList = null;
foreach ($waitList as $result) {
$result->waitIfPending();
while ($result->result instanceof Promise) {
$result = $result->result;
while (true) {
$result->waitIfPending();
if ($result->result instanceof Promise) {
$result = $result->result;
} else {
if ($result->result instanceof PromiseInterface) {
$result->result->wait(false);
}
break;
}
}
}
}

View file

@ -10,7 +10,7 @@ namespace GuzzleHttp\Promise;
*
* GuzzleHttp\Promise\queue()->run();
*/
class TaskQueue
class TaskQueue implements TaskQueueInterface
{
private $enableShutdown = true;
private $queue = [];
@ -30,30 +30,16 @@ class TaskQueue
}
}
/**
* Returns true if the queue is empty.
*
* @return bool
*/
public function isEmpty()
{
return !$this->queue;
}
/**
* Adds a task to the queue that will be executed the next time run is
* called.
*
* @param callable $task
*/
public function add(callable $task)
{
$this->queue[] = $task;
}
/**
* Execute all of the pending task in the queue.
*/
public function run()
{
/** @var callable $task */

View file

@ -0,0 +1,25 @@
<?php
namespace GuzzleHttp\Promise;
interface TaskQueueInterface
{
/**
* Returns true if the queue is empty.
*
* @return bool
*/
public function isEmpty();
/**
* Adds a task to the queue that will be executed the next time run is
* called.
*
* @param callable $task
*/
public function add(callable $task);
/**
* Execute all of the pending task in the queue.
*/
public function run();
}

View file

@ -14,13 +14,17 @@ namespace GuzzleHttp\Promise;
* }
* </code>
*
* @return TaskQueue
* @param TaskQueueInterface $assign Optionally specify a new queue instance.
*
* @return TaskQueueInterface
*/
function queue()
function queue(TaskQueueInterface $assign = null)
{
static $queue;
if (!$queue) {
if ($assign) {
$queue = $assign;
} elseif (!$queue) {
$queue = new TaskQueue();
}
@ -210,7 +214,7 @@ function unwrap($promises)
*
* @param mixed $promises Promises or values.
*
* @return Promise
* @return PromiseInterface
*/
function all($promises)
{
@ -243,7 +247,7 @@ function all($promises)
* @param int $count Total number of promises.
* @param mixed $promises Promises or values.
*
* @return Promise
* @return PromiseInterface
*/
function some($count, $promises)
{
@ -299,7 +303,7 @@ function any($promises)
*
* @param mixed $promises Promises or values.
*
* @return Promise
* @return PromiseInterface
* @see GuzzleHttp\Promise\inspect for the inspection state array format.
*/
function settle($promises)
@ -337,7 +341,7 @@ function settle($promises)
* @param callable $onFulfilled
* @param callable $onRejected
*
* @return Promise
* @return PromiseInterface
*/
function each(
$iterable,
@ -363,7 +367,7 @@ function each(
* @param callable $onFulfilled
* @param callable $onRejected
*
* @return mixed
* @return PromiseInterface
*/
function each_limit(
$iterable,
@ -387,7 +391,7 @@ function each_limit(
* @param int|callable $concurrency
* @param callable $onFulfilled
*
* @return mixed
* @return PromiseInterface
*/
function each_limit_all(
$iterable,
@ -441,60 +445,13 @@ function is_settled(PromiseInterface $promise)
}
/**
* Creates a promise that is resolved using a generator that yields values or
* promises (somewhat similar to C#'s async keyword).
* @see Coroutine
*
* When called, the coroutine function will start an instance of the generator
* and returns a promise that is fulfilled with its final yielded value.
* @param callable $generatorFn
*
* Control is returned back to the generator when the yielded promise settles.
* This can lead to less verbose code when doing lots of sequential async calls
* with minimal processing in between.
*
* use GuzzleHttp\Promise;
*
* function createPromise($value) {
* return new Promise\FulfilledPromise($value);
* }
*
* $promise = Promise\coroutine(function () {
* $value = (yield createPromise('a'));
* try {
* $value = (yield createPromise($value . 'b'));
* } catch (\Exception $e) {
* // The promise was rejected.
* }
* yield $value . 'c';
* });
*
* // Outputs "abc"
* $promise->then(function ($v) { echo $v; });
*
* @param callable $generatorFn Generator function to wrap into a promise.
*
* @return Promise
* @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
* @return PromiseInterface
*/
function coroutine(callable $generatorFn)
{
$generator = $generatorFn();
return __next_coroutine($generator->current(), $generator)->then();
}
/** @internal */
function __next_coroutine($yielded, \Generator $generator)
{
return promise_for($yielded)->then(
function ($value) use ($generator) {
$nextYield = $generator->send($value);
return $generator->valid()
? __next_coroutine($nextYield, $generator)
: $value;
},
function ($reason) use ($generator) {
$nextYield = $generator->throw(exception_for($reason));
// The throw was caught, so keep iterating on the coroutine
return __next_coroutine($nextYield, $generator);
}
);
return new Coroutine($generatorFn);
}