redshift

所属分类:数据挖掘/数据仓库
开发工具:PHP
文件大小:0KB
下载次数:0
上传日期:2016-10-26 11:17:59
上 传 者sh-1993
说明:  PHP 7中用于异步编程和通信的库。灵感来自goroutines和core.async。,
(Library for async programming and communication in PHP 7. Inspired by goroutines and core.async.,)

文件列表:
.travis.yml (274, 2016-10-26)
LICENSE (1079, 2016-10-26)
behat.yml (51, 2016-10-26)
composer.json (597, 2016-10-26)
composer.lock (64580, 2016-10-26)
examples/ (0, 2016-10-26)
examples/deadlock/ (0, 2016-10-26)
examples/deadlock/main.php (383, 2016-10-26)
examples/fibinacci/ (0, 2016-10-26)
examples/fibinacci/main.php (848, 2016-10-26)
examples/http-server/ (0, 2016-10-26)
examples/http-server/server.php (595, 2016-10-26)
features/ (0, 2016-10-26)
features/bootstrap/ (0, 2016-10-26)
features/bootstrap/FeatureContext.php (2323, 2016-10-26)
features/buffered_channels.feature (1305, 2016-10-26)
features/channels.feature (4796, 2016-10-26)
features/dropping_buffer.feature (804, 2016-10-26)
features/sliding_buffer.feature (798, 2016-10-26)
features/streams.feature (1189, 2016-10-26)
features/timeout.feature (831, 2016-10-26)
src/ (0, 2016-10-26)
src/Buffer/ (0, 2016-10-26)
src/Buffer/Buffer.php (933, 2016-10-26)
src/Buffer/BufferInterface.php (659, 2016-10-26)
src/Buffer/DroppingBuffer.php (982, 2016-10-26)
src/Buffer/SlidingBuffer.php (1019, 2016-10-26)
src/Channel/ (0, 2016-10-26)
src/Channel/Awaitable.php (1293, 2016-10-26)
src/Channel/Channel.php (3781, 2016-10-26)
src/Channel/ChannelInterface.php (437, 2016-10-26)
src/Channel/ChannelSelector.php (2730, 2016-10-26)
src/Channel/Message.php (644, 2016-10-26)
src/EventLoop/ (0, 2016-10-26)
src/EventLoop/EventLoop.php (2714, 2016-10-26)
... ...

## redshift [![Build Status](https://travis-ci.org/crystalplanet/redshift.svg?branch=master)](https://travis-ci.org/crystalplanet/redshift) [![Code Climate](https://codeclimate.com/github/crystalplanet/redshift/badges/gpa.svg)](https://codeclimate.com/github/crystalplanet/redshift) A PHP 7 library aimed at providing facilities for asynchronous programming and communication. Based on goroutines and core.async. ``` composer require crystalplanet/redshift ``` ## What problem does it solve ? PHP is great at serving web pages. But today we no longer talk about web pages but web applications, which are more complex than ever and have to meet the ever growing expectations. In order to do this, new ways of writing applications are necessary. Even though the language has drastically evolved, in most cases, it's still used as an oversophisticated template. Because of it's lack of concurrency features, PHP needs a process manager like Apaches *mod_php* or *php-fpm* to run on the server. Therefor the application has no control over it's lifetime and keeping track of stuff between the requests becomes very complicated. Redshift aims to provide way to achieve concurrency in PHP, as well as to provide means of communication between the processes, making way for a new generation of 'pure' applications. ## Explanation behind redshift ### Coroutines When calling normal PHP functions (more generally referred to as *subroutines*), the execution is expected to start at the first line and continue until a ```return``` statement or the end of the function is reached, or an exception is thrown. Once a function returns (or throws), the local state of the function is lost. Execution will start from the beginning if a function is called again. *Coroutines* are basically functions which keep their state inbetween calls. Instead of returning a value, they ```yield``` a series of values. PHP provides support for coroutines through [generators](http://php.net/manual/en/language.generators.overview.php). Even though it might not be so obvious at first, the very purpose of generators is to return the control of their execution to the caller, with the hope to regain it in the future. Redshift allows to take advantage of co-routines with minimal code overhead. In fact, the only thing that separates redshift code from any 'normal' PHP application, is the need to use ```yield``` every time there is synchronization between processes. ### Tasks and event loop By calling ```async()```, you're effectively creating a ```Task``` and queueing it for execution in the event loop. Even though all tasks run on a single thread, as PHP is single threaded, it's good to think of tasks as very very cheap processes. If PHP ever allows for working with threads by default, the library could be tweaked to run its tasks on a fixed thread pool, allowing for parallel execution. Each task has it's own call stack and works independently from other tasks. Regular functions can be executed asynchronously, but keep in mind that the function will block everything else that's in the queue until it's done. Synchronization of tasks should happen through channels. The event loop takes one callback as it's argument, with serves as a ```main()```. It then starts executing the ```main()```, along with all other asynchronous tasks that get queued up. It's worth noting that the event loop terminates itself as soon as the main has retrurned. It doesn't wait for any other tasks that might be awaiting execution. ### Channels Redshift is based on the theory of *Communicating Sequential Processes* (CSP), that also lies at the base of [goroutines](https://github.com/golang/go/wiki/LearnConcurrency) and [core.async](https://github.com/clojure/core.async). Proceses can communicate with each other by exchanging messages through channels. Operations on channels can be performed asynchronously (```put```, ```take```), and synchronously (```write```, ```read```). In case of the latter, the call is always preceded by the ```yield``` keyword, as the current coroutine is returning control of its execution to the caller - the event loop. This allows to synchronize the execution of different tasks. Channels use a ```BlockingBuffer``` by default. This means messages that a coroutine isn't allowed to execute past a write call to such channel if there is no other coroutine ready to read from it, and vice versa. Other buffer types can be used to achieve different behaviours. ## Examples You can find more examples with explanations in the [examples folder](https://github.com/crystalplanet/redshift/tree/master/examples). ### Bootstraping a redshift application Running a redshift application is as simple as writing: ```php use CrystalPlanet\Redshift\Redshift; Redshift::run(function () { echo 'Hello world!' . PHP_EOL; }); ``` ``` Hello World! ``` ### Running an asynchronous task Asynchronous tasks can be ran using ```async()```, which is actually just an alias for ```Redshift::async()```. Note that the example below will only output ```Quit```, as the main function doesn't wait for the execution of the async block. ```php use CrystalPlanet\Redshift\Redshift; Redshift::run(function () { async(function () { echo 'Hello World!' . PHP_EOL; }); echo 'Quit' . PHP_EOL; }); ``` ``` Quit ``` ### Using channels A channel can be used to make the main function wait for an exit signal before exiting. The main will be executed until ```$channel->read()```, which will block since the ```$channel``` is empty. It will resume once the async block has written ```Quit``` to the ```$channel```. ```php use CrystalPlanet\Redshift\Channel\Channel; use CrystalPlanet\Redshift\Redshift; Redshift::run(function () { $channel = new Channel(); async(function ($channel) { echo 'Hello World!' . PHP_EOL; yield $channel->write('Quit'); }, $channel); $message = yield $channel->read(); echo $message . PHP_EOL; }); ``` ``` Hello World! Quit ``` ### Buffered channels Buffered channels can be created by passing in a buffer as it's first argument. A buffered channel will allow to write to it without blocking, until the buffer is full. ```php use CrystalPlanet\Redshift\Buffer\Buffer; use CrystalPlanet\Redshift\Channel\Channel; use CrystalPlanet\Redshift\Redshift; Redshift::run(function () { $channel = new Channel(new Buffer(2)); // Won't block yield $channel->write(true); // Won't block yield $channel->write(true); // Will block yield $channel->write(true); }); ``` ### Timeouts In order to perform non-blocking waits, timeout channels can be used. Timeout channels are just regular channels on which a value will be sent after the specified amount of time. The code below will output ```Hello```, and append ``` World!``` after 1 second. ```php use CrystalPlanet\Redshift\Redshift; use CrystalPlanet\Redshift\Channel\Channel; use CrystalPlanet\Redshift\Time\Time; Redshift::run(function () { $timeout = Time::after(1000); echo 'Hello'; yield $timeout->read(); echo ' World!'; }); ``` ``` Hello World! ```

近期下载者

相关文件


收藏者