Giter Club home page Giter Club logo

async's Introduction

ReactPHP Logo

Event-driven, non-blocking I/O with PHP.

Build Status

ReactPHP is a low-level library for event-driven programming in PHP. At its core is an event loop, on top of which it provides low-level utilities, such as: Streams abstraction, async DNS resolver, network client/server, HTTP client/server and interaction with processes. Third-party libraries can use these components to create async network clients/servers and more.

<?php

// $ composer require react/http react/socket # install example using Composer
// $ php example.php # run example on command line, requires no additional web server

require __DIR__ . '/vendor/autoload.php';

$server = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
    return React\Http\Message\Response::plaintext(
        "Hello World!\n"
    );
});

$socket = new React\Socket\SocketServer('127.0.0.1:8080');
$server->listen($socket);

echo "Server running at http://127.0.0.1:8080" . PHP_EOL;

This simple web server written in ReactPHP responds with "Hello World!" for every request.

ReactPHP is production ready and battle-tested with millions of installations from all kinds of projects around the world. Its event-driven architecture makes it a perfect fit for efficient network servers and clients handling hundreds or thousands of concurrent connections, long-running applications and many other forms of cooperative multitasking with non-blocking I/O operations. What makes ReactPHP special is its vivid ecosystem with hundreds of third-party libraries allowing you to integrate with many existing systems, such as common network services, database systems and other third-party APIs.

  • Production ready and battle-tested.
  • Rock-solid with stable long-term support (LTS) releases.
  • Requires no extensions and runs on any platform - no excuses!
  • Takes advantage of optional extensions to get better performance when available.
  • Highly recommends latest version of PHP 7+ for best performance and support.
  • Supports legacy PHP 5.3+ and HHVM for maximum compatibility.
  • Well designed and reusable components.
  • Decoupled parts so they can be replaced by alternate implementations.
  • Carefully tested (unit & functional).
  • Promotes standard PSRs where possible for maximum interoperability.
  • Aims to be technology neutral, so you can use your preferred application stack.
  • Small core team of professionals supported by large network of outside contributors.

ReactPHP is non-blocking by default. Use workers for blocking I/O. The event loop is based on the reactor pattern (hence the name) and strongly inspired by libraries such as EventMachine (Ruby), Twisted (Python) and Node.js (V8).

This repository you're currently looking at is mostly used as a meta repository to discuss and plan all things @ReactPHP. See the individual components linked below for more details about each component, its documentation and source code.

Core Components

Network Components

Utility Components

Built with ReactPHP

  • Thruway PHP Client and Router Library for Autobahn and WAMP (Web Application Messaging Protocol) for Real-Time Application Messaging voryx/Thruway

  • PPM - PHP Process Manager PPM is a process manager, supercharger and load balancer for modern PHP applications. php-pm/php-pm

  • php-ar-drone 🚁 Port of node-ar-drone which allows user to control a Parrot AR Drone over PHP jolicode/php-ar-drone

  • Ratchet Asynchronous WebSocket server ratchetphp/Ratchet

  • Predis\Async Asynchronous PHP client library for Redis built on top of ReactPHP nrk/predis-async

  • clue/redis-server A Redis server implementation in pure PHP clue/redis-server

And many more on our wiki page Β»

Articles

  • Sergey Zhuk A series of articles covering ReactPHP: from the basics to the real application examples. sergeyzhuk.me

  • Cees-Jan Kiewiet Blog series about several ReactPHP components and how they work. blog.wyrihaximus.net

  • LoΓ―c Faugeron Super Speed Symfony - ReactPHP. gnugat.github.io

  • Marc J. Schmidt Bring High Performance Into Your PHP App (with ReactPHP). marcjschmidt.de

  • Marc Morera When ReactPHP meet Symfony medium.com/@apisearch

Talks

Getting started

ReactPHP consists of a set of individual components. This means that instead of installing something like a "ReactPHP framework", you actually pick only the components that you need.

This project follows SemVer for all its stable components. The recommended way to install these components is through Composer. New to Composer?

For example, this may look something like this:

# recommended install: pick required components
composer require react/event-loop react/http

As an alternative, we also provide a meta package that will install all stable components at once. Installing this is only recommended for quick prototyping, as the list of stable components may change over time. This meta package can be installed like this:

# quick protoyping only: install all stable components
composer require react/react:^1.4

For more details, check out ReactPHP's homepage for quickstart examples and usage details.

See also the combined changelog for all ReactPHP components for details about version upgrades.

Support

Do you have a question and need help with ReactPHP? Don't worry, we're here to help!

As a first step, check the elaborate documentation that comes with each component (see links to individual documentation for each component above). If you find your question is not answered within the documentation, there's a fair chance that it may be relevant to more people. Please do not hesitate to file your question as an issue in the relevant component so others can also participate.

You can also check out our official Gitter chat room. Most of the people involved in this project are available in this chat room, so many questions get answered in a few minutes to some hours. We also use this chat room to announce all new releases and ongoing development efforts, so consider staying in this chat room for a little longer.

Also follow @reactphp on Twitter for updates. We use this mostly for noteworthy, bigger updates and to keep the community updated about ongoing development efforts. You can always use the #reactphp hashtag if you have anything to share!

We're a very open project and we prefer public communication whenever possible, so that more people can participate and help getting the best solutions available. At the same time, we realize that some things are better addressed in private. Whether you just want to say thank you, want to report a security issue or want to help sponsor a certain feature development, you can reach out to the core team in private by sending an email to [email protected]. Please keep in mind that we're a small team of volunteers and do our best to support anybody reaching out.

Do you want to support ReactPHP? Awesome! Let's start with letting the the world know why you think ReactPHP is awesome and try to help others getting on board! Send a tweet, write a blog post, give a talk at your local user group or conference or even write a book. There are many ways you can help. You can always reach out to us in private and help others in our support channels. Thank you!

Tests

To run the test suite, you first need to clone this repo and then install all dependencies through Composer:

composer install

To run the test suite, go to the project root and run:

vendor/bin/phpunit

The test suite also contains a number of functional integration tests that rely on a stable internet connection. Due to the vast number of integration tests, these are skipped by default during CI runs. If you also do not want to run these, they can simply be skipped like this:

vendor/bin/phpunit --exclude-group internet

License

MIT, see LICENSE.

async's People

Contributors

cboden avatar clue avatar igorw avatar nhedger avatar simonfrings avatar wyrihaximus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

async's Issues

Support Promise v3

We should support Promise v3 for Async v2, v3 and v4. I don't think implementing this here requires a lot of work, the only outstanding feature that would be debatable is cancellation semantics as discussed in #42.

I'm not currently working on this, but figured it makes sense to report here in order to track this feature request. In case anybody feels like picking this up, any input and PRs would be much appreciated πŸ‘

Struggling with the simplest example

Hi everybody,

<?php
require __DIR__ . '/async/vendor/autoload.php';

use React\EventLoop\Loop;
use React\Promise\Promise;
use function React\Async\await;
use function React\Async\async;


Loop::addTimer(0.5, React\Async\async(function() {
    echo 'a';
    React\async\await(React\Promise\Timer\sleep(1.0));
    echo 'c'; // not echoed?
}));

Loop::addTimer(1.0, fn() => echo 'b'); // line 16

I am already struggling with the simplest example (copied from the main page).
I am using PHP 8.1.2 on Win10 with the newest async.

  1. There is an unexpected token "echo" in line 16.
  2. When I comment line 16 with // in the beginning, the output is just 'a' (without 'c') - why not 'ac'?

Thank you!

Allow `iterable` instead of `array` for `parallel()`, `series()` and `waterfall()`

We should support accepting an iterable instead of only an array for parallel(), series() and waterfall(). The iterable pseudo type is available as of PHP 7.1, so we can take advantage of this for our Async v3 and Async v4 (see also #11 and #14). It supports passing an array just like now, but also accepts Iterators and Generators.

I'm not currently working on this, but figured it makes sense to report here in order to track this feature request. In case anybody feels like picking this up, any input and PRs would be much appreciated πŸ‘ (I've also filed the same suggestion for Promise v3 in reactphp/promise#221)

await() error in SimpleFiber.php

(Great job with Fibers initiative!)
For test purposes I'm refactoring my app with await() function in place of promises-chains. I've got an error:

2021-11-29 21:56:23 [EXCEPTION] Error: Value of type null is not callable in ...\vendor\react\async\src\SimpleFiber.php:59
2021-11-29 21:56:23 [EXCEPTION] #0 ...\vendor\react\async\src\functions.php(92): React\Async\SimpleFiber->suspend()
2021-11-29 21:56:23 [EXCEPTION] #1 ...\MessagesProcessor.php(114): React\Async\await(Object(React\Promise\Promise))

It occurs when I try to use async() function. It's hard to say how to reproduce this bug. In the same call stack, a few promises before, I use a React\Http\Browser with async() function. If I comment this usage (replace to something like resolve(new ResultObject())) - error doesn't occur. If I use Browser with promise-style api, the PHP process ends with error:

Process finished with exit code -1073741819 (0xC0000005)

I'm using the newest versions of all packages, ofc PHP 8.1.
Do you know what can cause these errors?

Use 0.x versions

Hello there,

Now that react/async is open to public, would you consider using 0.x.x versions until 1.0 is not finalized instead of relying on commit hashes?

It took me a while after realizing an important BC break introduced by 4355fcf after a composer update 🀠

With a semver-like approach, BC breaks would be easier to spot. WDYT?

Error: event_base_loop reentrant invocation

Hello.
The following code is causing an error:
EventBase::loop(): event_base_loop: reentrant invocation. Only one event_base_loop can run on each event_base at once.

<?php

use React\EventLoop\Loop;
use React\Promise\Deferred;
use function React\Async\await;

require __DIR__  . '/vendor/autoload.php';

Loop::addTimer(0, function () {
	$deferred = new Deferred();
	Loop::addTimer(0, static fn() => $deferred->resolve());
	await($deferred->promise());
});

Tested on ExtEventLoop.

Cancellation semantics for `async()` and `coroutine()`

What should the following code return?

$promise = async(static function (): int {
    try {
        await(React\Promise\Timer\sleep(2));
    } catch (Exception $e) {
        return 1;
    }

    return 2;
})();

$promise->cancel();

var_dump(await($promise));

At the moment, the code would print 1. The same cancellation logic is triggered for fibers (#20) and coroutines (#13). Accordingly, this affects Async v3 and Async v4.

Perhaps we should reject the entire promise? (See also reactphp/promise#56 for discussion about cancellation semantics in Promise v3).

Improve error reporting when incorrectly using `await()` (Value of type null is not callable in src/SimpleFiber.php:66)

Reproduce:

use React\EventLoop\Factory as Loop;
use React\Async;
use React\Promise\Deferred;

$loop = Loop::create();

$deferred = new Deferred;
$promise = $deferred->promise();
$loop->addTimer(0.02, function() use($deferred) {
    $deferred->resolve();
});

$foo = function() use($promise) {
    Async\await($promise);
    echo 'All good' . PHP_EOL;    
};

$loop->addTimer(0.01, $foo);

$loop->run();

How to fix it is known: wrap $foo into Async\async. But the error sucks anyway. You guys gotta find a way to get it either work anyway, or throw a nice error telling us what is wrong and hinting what to do.

await() doesn't work with streaming HTTP response body

Hello,

The code below doesn't work as expected.
At the end, strlen() should return a non-zero.

Am I missing something maybe?

<?php
require __DIR__ . '/vendor/autoload.php';

React\Async\async(function (): void {
	$browser = new React\Http\Browser();
	$response = $browser->requestStreaming(
		'GET',
		'https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_1920_18MG.mp4',
		[
			'Range' => 'bytes=0-499',
		],
	);

	/** @var Psr\Http\Message\ResponseInterface */
	$response = React\Async\await($response);

	/** @var React\Stream\ReadableStreamInterface */
	$body = $response->getBody();

	$body = React\Promise\Stream\buffer($body);
	$body = React\Async\await($body);

	echo strlen($body), "\n"; // 0
})();

Using await in a destructor

πŸ‘‹ I've ran into an issue with using await in a destructor. The error triggered is Fatal error: Uncaught FiberError: Cannot switch fibers in current execution context in SimpleFiber.php on line 66.

index.php

<?php

declare(strict_types=1);

use function React\Async\await;

require_once __DIR__ . '/vendor/autoload.php';

$foo = new class {

    public function __construct()
    {
        await(\React\Promise\Timer\sleep(1));
        print "construct\n";
    }

    public function __destruct()
    {
        await(\React\Promise\Timer\sleep(1));
        print "destruct\n";
    }

};

Using the 4.x branch; the issue seems to exit with both StreamSelectLoop and ExtUvLoop.

\React\Async\async did not invokes in on('data') event

I have TCP client

$connector = new \React\Socket\Connector(); that connect to server and listen.

I add handler to 'data' event.

// did not write to event.log
$connector = new \React\Socket\Connector();
$connector->connect($host)->then(function (\React\Socket\ConnectionInterface $connection) {
    $connection->on('data', \React\Async\async(
        function ($data) {
            file_put_contents('/home/carsak/event.log', $data . PHP_EOL, FILE_APPEND);
        }
    ));
});

function inside async did not invoked

but if I wrote without async function, function write logs into event.log file

// it works
$connector = new \React\Socket\Connector();
$connector->connect($host)->then(function (\React\Socket\ConnectionInterface $connection) {
    $connection->on('data',
        function ($data) {
            file_put_contents('/home/bitrix/dialer/event.log', $data . PHP_EOL, FILE_APPEND);
        }
    );
});

I checked docs several times and read about

The async() function is specifically designed for cases where it is used as a callback (such as an event loop timer, event listener, or promise callback). For this reason, it returns a new function wrapping the given $function instead of directly invoking it and returning its value.

Follow the example

use function React\Async\async;

Loop::addTimer(1.0, async(function () { … }));
$connection->on('close', async(function () { … }));
$stream->on('data', async(function ($data) { … }));
$promise->then(async(function (int $result) { … }));

My composer.json

{
  "require": {
    "react/socket": "1.12",
    "react/event-loop": "1.3",
    "ext-pdo": "*",
    "ext-curl": "*",
    "monolog/monolog": "^2.9",
    "elasticsearch/elasticsearch": "^8.8",
    "react/async": "^4.2"
  },
  "config": {
    "allow-plugins": {
      "php-http/discovery": true
    }
  }
}

What I did wrong?

Basic question 'bout reactphp

Hi,

Sorry, for this - again - basic question about reactphp

To make my question more clear, I use this DNS lookup example:

<?php
$result = [];
$domains = ['domain1.com', 'domain2.xyz'];

foreach ($domains as $domain) {
    $result[] = dns_get_record($domain);
}

var_dump($result);

Can above example executed in parallel (to make it faster) with reactphp or not (and if yes, how with async? or event-loop? can you give me an additional hint)?
If I understand this stackoverflow post correctly, it can not (but I do not think so).

Thank you again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.