Various utilities for ReactPHP.

  • 2 heads
  • 1 release
  • git clone https://klva.cz/src/php/react-awaited.git
  • Initial commit. 47b3081, 31 May 2019
    src/
    tests/
    .gitattributes
    .gitignore
    composer.json
    LICENSE.md
    README.md

    Awaited

    Provides various utilities for ReactPHP.

    Semaphore

    Limits maximum number of concurrently executing tasks.

    $semaphore = new Semaphore($limit = 1, $initial = 0);
    
    $semaphore->await(function(callable $complete): void {
        
        // Do something on shared resource...
        
        $complete(); // or $semaphore->release();
    
    });
    

    Timer

    Advanced timer implementation with pausing, resetting and variable interval support.

    $timer = new Timer($loop, 1.0, $periodic);
    
    // This will be called everytime the interval elapses.
    $timer->add($callback);
    
    // This will be called next time the timer elapses.
    $timer->await()->then($callback);
    
    // Stores remaining time and halts execution.
    $timer->pause();
    
    // Restores execution.
    $timer->start();
    
    // Resets interval without executing bound handlers.
    $timer->restart();
    
    // Executes bound handlers and resets interval.
    $timer->elapse();
    
    // Stops the timer (you can start it again later).
    $timer->stop();
    
    // Changes interval.
    $timer->setInterval(2.0);
    
    // Toggles repeating.
    $timer->setPeriodic(false);
    

    Code above should be self-explanatory enough, just a note for changing interval - it takes an effect immediately. In other words, if you set shorter interval which is actually in the past, timer will elapse immediately. If you set higher interval than the current, execution will be delayed (e.g. when changing from 1 second to 3 seconds, next elapse will happen 2 seconds later).

    Internally, this implementation uses underlying native event loop timer.

    Awaitable chain

    Both Semaphore and Timer use Awaitable interface. You can combine both of them to create some sort of rate limiter:

    $timer = new Timer($loop, 1.0);
    $semaphore = new Semaphore(2);
    
    $limiter = new Awaitables($timer, $semaphore, ...);
    
    // This will execute at most once per second, no more than 2 concurrent tasks at the same time.
    $limiter->each(function(callable $complete): void {
    
        // Do some work...
    
        // Always do this, so semaphore is aware of release.
        $complete();
    
    });
    
    // Awaitables implements Awaitable interface by itself, so you can:
    $limiter->await()->then($callback);