Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
olvlvl committed Jan 21, 2018
0 parents commit 8505c26
Show file tree
Hide file tree
Showing 11 changed files with 887 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
root = true

[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4

[*.yml]
indent_style = space
indent_size = 2

[*.md]
indent_style = space
indent_size = 4

[Makefile]
indent_style = tab
indent_size = 4
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build
composer.lock
vendor
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
sudo: false

cache:
directories:
- $COMPOSER_CACHE_DIR
- $HOME/.composer/cache
- $TRAVIS_BUILD_DIR/build

language: php

php:
- 7.1
- 7.2

before_script:
- if [[ $TRAVIS_PHP_VERSION != "7.1" ]]; then phpenv config-rm xdebug.ini; fi

script:
- if [[ $TRAVIS_PHP_VERSION == "7.1" ]]; then make test-coveralls; else make test; fi
30 changes: 30 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
The olvlvl/delayed-event-dispatcher package is free software.
It is released under the terms of the following BSD License.

Copyright (c) 2018 by Olivier Laviale
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

* Neither the name of Olivier Laviale nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 changes: 49 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# customization

PACKAGE_NAME = olvlvl/delayed-event-dispatcher
PACKAGE_VERSION = 0.1
PHPUNIT = phpunit

# do not edit the following lines

all: vendor

usage:
@echo "test: Runs the test suite.\ndoc: Creates the documentation.\nclean: Removes the documentation, the dependencies and the Composer files."

vendor:
@COMPOSER_ROOT_VERSION=$(PACKAGE_VERSION) composer install

update:
@COMPOSER_ROOT_VERSION=$(PACKAGE_VERSION) composer update

autoload: vendor
@composer dump-autoload

test: all
@$(PHPUNIT)

test-coverage: all
@mkdir -p build/coverage
@$(PHPUNIT) --coverage-html build/coverage

test-coveralls: all
@mkdir -p build/logs
COMPOSER_ROOT_VERSION=$(PACKAGE_VERSION) composer require satooshi/php-coveralls '^2.0'
@$(PHPUNIT) --coverage-clover build/logs/clover.xml
php vendor/bin/php-coveralls -v

doc: vendor
@mkdir -p build/docs
@apigen generate \
--source lib \
--destination build/docs/ \
--title "$(PACKAGE_NAME) v$(PACKAGE_VERSION)" \
--template-theme "bootstrap"

clean:
@rm -fR build
@rm -fR vendor
@rm -f composer.lock

.PHONY: all autoload doc clean test test-coverage test-coveralls update
232 changes: 232 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
# DelayedEventDispatcher

[![Release](https://img.shields.io/packagist/v/olvlvl/delayed-event-dispatcher.svg)](https://packagist.org/packages/olvlvl/delayed-event-dispatcher)
[![Build Status](https://img.shields.io/travis/olvlvl/delayed-event-dispatcher.svg)](http://travis-ci.org/olvlvl/delayed-event-dispatcher)
[![Code Quality](https://img.shields.io/scrutinizer/g/olvlvl/delayed-event-dispatcher.svg)](https://scrutinizer-ci.com/g/olvlvl/delayed-event-dispatcher)
[![Code Coverage](https://img.shields.io/coveralls/olvlvl/delayed-event-dispatcher.svg)](https://coveralls.io/r/olvlvl/delayed-event-dispatcher)
[![Packagist](https://img.shields.io/packagist/dt/olvlvl/delayed-event-dispatcher.svg)](https://packagist.org/packages/olvlvl/delayed-event-dispatcher)

The `olvlvl/delayed-event-dispatcher` package provides an event dispatcher that delays event dispatching to a later time
in the application life.

A delayed event dispatcher is useful to reduce the response time of your HTTP application when events can perfectly be
dispatched after the response has been sent. For instance, updating an entity that would require clearing cache,
performing projections, or reindexing, all of which have nothing to do with the response itself.

Because you're probably using one event dispatcher for your application you don't want all events to be delayed, most of
them have to be dispatched immediately for your application to run properly, that's why you can specify an arbiter to
determine which events to delay and which not to.

Finally, because you want all delayed events to be dispatched when you flush them—even when an exception is thrown—you
can provide an exception handler. It's up to you to decide what to do with them. You'll probably want to recover, log
the exception, and continue with dispatching the other events.

**Disclaimer:** The delayed event dispatcher is a decorator that is meant to be used together with
[symfony/event-dispatcher][].





## Instantiating a delayed event dispatcher

The delayed event dispatcher is a decorator, which means you'll need another event dispatcher to decorate. Methods are
forwarded to the decorated instance, except of course for the `dispatch()` method.

```php
<?php

use olvlvl\DelayedEventDispatcher\DelayedEventDispatcher;

/* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher */

$delayedEventDispatcher = new DelayedEventDispatcher($eventDispatcher);
$delayedEventDispatcher->addListener('my_event', $listener);
```





### Instantiating an inactive delayed event dispatcher

By default the delayed event dispatcher is _active_, which means it will delay events. This is fine for your HTTP
application, but that's not something you want for the console or the consumer application. You can create a _disabled_
delayed event dispatcher be defining the `disabled` option as `true`.

```php
<?php

use olvlvl\DelayedEventDispatcher\DelayedEventDispatcher;

/* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher */

$disabledDelayedEventDispatcher = new DelayedEventDispatcher($eventDispatcher, true);
```

This is especially useful when your HTTP/console/consumer applications are deployed using the same artifact, that you
can customize using environment variables.

```php
<?php

use olvlvl\DelayedEventDispatcher\DelayedEventDispatcher;

/* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher */

$disabledDelayedEventDispatcher = new DelayedEventDispatcher(
$eventDispatcher,
filter_var(getenv('MYAPP_DISABLE_DELAYED_EVENT_DISPATCHER'), FILTER_VALIDATE_BOOLEAN)
);
```





## Dispatching delayed events

Delayed events are dispatched with the `flush()` method.

```php
<?php

use olvlvl\DelayedEventDispatcher\DelayedEventDispatcher;

/* @var DelayedEventDispatcher $delayedEventDispatcher */

$delayedEventDispatcher->dispatch('my_event');
$delayedEventDispatcher->dispatch('my_other_event');
$delayedEventDispatcher->flush();
```





## Deciding which events to delay and which not to

By default all events are delayed—if the delayed event dispatcher was created with `disabled = false`—but you can supply
an arbiter to choose which events to delay and which not to. You can use the `Delayable` interface to mark your events,
but it's not a requirement. The arbiter is a simple callable, its implementation is up to you.

```php
<?php

use olvlvl\DelayedEventDispatcher\Delayable;
use olvlvl\DelayedEventDispatcher\DelayedEventDispatcher;
use Symfony\Component\EventDispatcher\Event;

$arbiter = function (string $eventName, Event $event) {
return $event instanceof Delayable;
};

/* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher */

$disabledDelayedEventDispatcher = new DelayedEventDispatcher($eventDispatcher, false, $arbiter);
```





## Handling exceptions

By default exceptions thrown during the dispatching of events are not recovered, the dispatching halts, leaving delayed
events in the queue. If you want to recover from these exceptions, and make sure all the events are dispatched, you'll
want to provide and exception handler.

```php
<?php

use olvlvl\DelayedEventDispatcher\DelayedEventDispatcher;
use Symfony\Component\EventDispatcher\Event;

/* @var \Psr\Log\LoggerInterface $logger */

$exceptionHandler = function (\Throwable $error, string $eventName, Event $event = null) use ($logger) {
// The exception is recovered, we log it to fix it later
$logger->danger($error);
};

/* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher */

$disabledDelayedEventDispatcher = new DelayedEventDispatcher($eventDispatcher, false, null, $exceptionHandler);
```





----------





## Requirements

The package requires PHP 7.1 or later.





## Installation

The recommended way to install this package is through [Composer](http://getcomposer.org/):

$ composer require olvlvl/delayed-event-dispatcher





### Cloning the repository

The package is [available on GitHub](https://github.com/olvlvl/delayed-event-dispatcher),
its repository can be cloned with the following command line:

$ git clone https://github.com/olvlvl/delayed-event-dispatcher.git





## Documentation

You can generate the documentation for the package and its dependencies with the `make doc` command.
The documentation is generated in the `build/docs` directory. [ApiGen](http://apigen.org/) is
required. The directory can later be cleaned with the `make clean` command.





## Testing

The test suite is ran with the `make test` command. [PHPUnit](https://phpunit.de/) and
[Composer](http://getcomposer.org/) need to be globally available to run the suite. The command
installs dependencies as required. The `make test-coverage` command runs test suite and also creates
an HTML coverage report in `build/coverage`. The directory can later be cleaned with the
`make clean` command.

The package is continuously tested by [Travis CI](http://about.travis-ci.org/).

[![Build Status](https://img.shields.io/travis/olvlvl/delayed-event-dispatcher.svg)](http://travis-ci.org/olvlvl/delayed-event-dispatcher)
[![Code Coverage](https://img.shields.io/coveralls/olvlvl/delayed-event-dispatcher.svg)](https://coveralls.io/r/olvlvl/delayed-event-dispatcher)





## License

**olvlvl/delayed-event-dispatcher** is licensed under the New BSD License - See the [LICENSE](LICENSE) file for details.






[symfony/event-dispatcher]: https://github.com/symfony/event-dispatcher
27 changes: 27 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "olvlvl/delayed-event-dispatcher",
"description": "Delays the dispatching of events",
"keywords": [ "symfony", "event", "dispatcher", "delay" ],
"type": "library",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Olivier Laviale",
"email": "olivier.laviale@gmail.com"
}
],
"require": {
"php": ">=7.1.3",
"symfony/event-dispatcher": "^4.0"
},
"autoload": {
"psr-4": {
"olvlvl\\DelayedEventDispatcher\\": "lib"
}
},
"autoload-dev": {
"psr-4": {
"olvlvl\\DelayedEventDispatcher\\": "tests"
}
}
}

0 comments on commit 8505c26

Please sign in to comment.