PHPackages                             hurah/events - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. hurah/events

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

hurah/events
============

Event handling / task delegation system based on inotifywait

v1.0.26(2y ago)02.4k↓66.7%MITPHPPHP ^8.3CI failing

Since Oct 22Pushed 1y ago1 watchersCompare

[ Source](https://github.com/antonboutkam/hurah-events)[ Packagist](https://packagist.org/packages/hurah/events)[ RSS](/packages/hurah-events/feed)WikiDiscussions main Synced 2d ago

READMEChangelogDependencies (4)Versions (16)Used By (0)

Hurah events
============

[](#hurah-events)

A simple file based task delegation solution.

> ⚠️ **No locking**: This package is intended as a simple solution for task delegation in situations where scaling won't be an issue. It assumes each handler for a specific task runs only once. Running multiple instances of the same handler concurrently may result in tasks being executed multiple times.

Use cases
---------

[](#use-cases)

- Make generic software extensible.
- Move time consuming work to a separate background process.
- Prevent slow or possibly unavailable resources from slowing down the performance of your system.

Installation
------------

[](#installation)

```
    composer require hurah/events

```

Setup
-----

[](#setup)

Since this is a file based system, an empty directory is needed for the system to store it's data in. Running the handler can probably best be done with something like Inotifywait if you want to have the event handler to run as close to real-time as possible. A cron job could also be used if some delay is not an issue and Inotifywait cannot be installed.

Dispatch an event
-----------------

[](#dispatch-an-event)

From the code where a task or some tasks need to be delegated

```
$exampleContextData = ['product_id' => 123];
$dispatcher = new Dispatcher('/some/root/directory/where/events/will/live');
$dispatcher->dispatch('product/created', $exampleContextData);

```

Implement handler(s)
--------------------

[](#implement-handlers)

Create a new class and have it extend AbstractHandler. In it's most basic form your handler will only implement handleTask which you should use to implement the logic required to do whatever job you have in mind.

```
class MyHandler extends AbstractHandler
{
    protected function handleTask(Context $myTaskData): int
    {
      return Task::SUCCESS;
    }
}

```

### Return type and failures

[](#return-type-and-failures)

When implementing your handler as above, you must return the right directive for the handler to know what to do next.

ReturnActionTask::SUCCESSThe task will be moved to an archive directory.Task::INVALIDThe task will be moved to an error directory for later manual processing / debugging / analysis. The handler will continue to process all other tasks waiting in the queueTask::FAILUREProcessing of tasks is terminated, leaving the task that caused the problem in your inbox as the first task to pick up as soon as the failure is resolved.Task::RETRYThe task will stay in the inbox, an attempt will be done in the next run to process the task, this will be repeated until maxAttempts() is reached which you must implement your self as maxAttempts() defautls to 0. Be carefull not to clog up your system. When the maximum number of attempts is hit the task is moved to the error directory.Events
------

[](#events)

When an event is dispatched, it’s identified by a unique name (e.g. product/created), which any number of handlers might be listening to. A sepearate json file containing the context data is stored for each handler. When the handler is triggered each job is executed in sequential order.

### Event tree

[](#event-tree)

The event type is made up out of one or more strings separated by a forward slash. Event listeners can be bound to any level of the event tree. A listener that is set up to listen for "product" events will be triggered when a "product/created" event was dispatched etc.

Running handlers
----------------

[](#running-handlers)

You need some mechanism to trigger the handler code on demand or (not favorable) run the handler code periodically to check for new events and handle them.

#### Manual / periodically

[](#manual--periodically)

```
php bin/application.php worker:runner

```

ArgumentDescriptionhandler\_nameName used to uniquely identify this handler, will be mapped to an automatically created folder on disk.event\_typeThe type of event that this handler will receivehandlerFully qualified name of the class that implements the handling logic (e.g. MyNamespace\\MyHandler)event\_rootShould match with whatever you chose to be the root of your events#### On demand / automatically

[](#on-demand--automatically)

The bin folder contains the bash script below which you can use to monitor event directories. This script should run an a per event basis, probably using supervisor or perhaps systemd to autorestart in case something fails.

```
#!/bin/sh

# Usage:
# ./inotify-wait.sh
#

echo "Starting listener in $1"
DIRECTORY="$1/$3/$2_listener/inbox"

echo "Event directory $DIRECTORY";

if [ ! -d "$DIRECTORY" ]; then
  echo "Creating $DIRECTORY which will act as the event inbox"
  mkdir -p "$DIRECTORY"
fi

inotifywait -m "$DIRECTORY" -e create |
    while read path action file; do
	       echo "$action - $path - $file"
	       /usr/bin/pwd
        /usr/bin/php ./application.php worker:runner $2 $3 $4 $1
    done

echo "Listener stopped"

```

[![antonboutkam](https://camo.githubusercontent.com/cee6bc0073a20e354bd29907a9064cf93b8dfad36fe13ec01af5b65e1a2e8efa/68747470733a2f2f636972636c6563692e636f6d2f67682f616e746f6e626f75746b616d2f68757261682d6576656e74732e7376673f7374796c653d737667)](https://antonboutkam.nl)

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance29

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~69 days

Recently: every ~63 days

Total

15

Last Release

751d ago

PHP version history (2 changes)v1.0.1PHP ^7.4

v1.0.26PHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/27406772?v=4)[⚒ Anton Boutkam](/maintainers/antonboutkam)[@antonboutkam](https://github.com/antonboutkam)

---

Top Contributors

[![antonboutkam](https://avatars.githubusercontent.com/u/27406772?v=4)](https://github.com/antonboutkam "antonboutkam (41 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hurah-events/health.svg)

```
[![Health](https://phpackages.com/badges/hurah-events/health.svg)](https://phpackages.com/packages/hurah-events)
```

###  Alternatives

[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.7k38.9k](/packages/matomo-matomo)[composer/composer

Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.

29.5k196.2M3.1k](/packages/composer-composer)[phpro/soap-client

A general purpose SoapClient library

8896.1M54](/packages/phpro-soap-client)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)[blackfire/player

A powerful web crawler and web scraper with Blackfire support

49617.1k](/packages/blackfire-player)[dagger/dagger

Dagger PHP SDK

261.1k](/packages/dagger-dagger)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
