Skip to content

API reference ​

Public types in src/ for 6.x. Paths are relative to the package root. Examples elsewhere in this guide are the place for full scripts.

Tomaj\Hermes\Message ​

src/Message.php. Implements MessageInterface.

php
public function __construct(
    string $type,
    ?array $payload = null,
    ?string $messageId = null,
    ?float $created = null,
    ?float $executeAt = null,
    int $retries = 0
)
MethodReturns
getId()string. UUID v4 when the constructor id was null (the default) or ''; any other string, including "0", is returned as given.
getCreated()float. microtime(true) when omitted.
getExecuteAt()float|null
getType()string
getPayload()array|null
getRetries()int

There is no setter and no priority property.

Tomaj\Hermes\MessageInterface ​

src/MessageInterface.php. The six getters above.

Tomaj\Hermes\Emitter ​

src/Emitter.php. Implements EmitterInterface.

php
public function __construct(DriverInterface $driver, ?LoggerInterface $logger = null)

public function emit(MessageInterface $message, int $priority = Dispatcher::DEFAULT_PRIORITY): EmitterInterface

Calls Driver::send. Logs at info when $logger is set. Returns $this. Throws UnknownPriorityException when the driver does.

Tomaj\Hermes\EmitterInterface ​

src/EmitterInterface.php. The emit() method above.

Tomaj\Hermes\Dispatcher ​

src/Dispatcher.php. Implements DispatcherInterface.

php
public const int DEFAULT_PRIORITY = 100;

public function __construct(
    DriverInterface $driver,
    ?LoggerInterface $logger = null,
    ?ShutdownInterface $shutdown = null,
    ?Randomizer $randomizer = null
)

When $shutdown is not null and the driver has setShutdown(), the constructor calls it. $randomizer (Random\Randomizer) supplies the retry jitter; it defaults to new Randomizer(). See Retry.

MethodBehavior
emit(MessageInterface $message, int $priority = self::DEFAULT_PRIORITY): DispatcherInterfaceDeprecated. Sends through the driver and logs. Prefer Emitter.
handle(array $priorities = []): voidBlocks in Driver::wait. Catches ShutdownException and logs a notice. Catches other Exceptions, logs them at error, writes them to Tracy when Tracy is installed and enabled, and rethrows them.
registerHandler(string $type, HandlerInterface $handler): DispatcherInterfaceAppends one handler for $type.
registerHandlers(string $type, array $handlers): DispatcherInterfaceCalls registerHandler for each.
unregisterHandler(string $type, HandlerInterface $handler): DispatcherInterfaceDrops that instance for that type.
unregisterAllHandlers(): DispatcherInterfaceClears the map.

handle()'s array is a list of priority integers. Empty means all queues the driver has.

Handler exceptions are caught per handler. They do not leave handle() unless the driver itself throws. Retry is described in Retry. The private delay formula is microtime(true) + $retries ** 4 + 15 + $randomizer->getInt(1, 30) * ($retries + 1).

Tomaj\Hermes\DispatcherInterface ​

src/DispatcherInterface.php. registerHandler, registerHandlers, unregisterAllHandlers, unregisterHandler, handle. emit() is only on the concrete class.

Tomaj\Hermes\Driver\DriverInterface ​

src/Driver/DriverInterface.php.

php
public function send(MessageInterface $message, int $priority = Dispatcher::DEFAULT_PRIORITY): bool;

public function setupPriorityQueue(string $name, int $priority): void;

public function wait(Closure $callback, array $priorities): void;

send() may throw SerializeException or UnknownPriorityException. setupPriorityQueue() may throw NotSupportedException. wait() may throw UnknownPriorityException or ShutdownException.

Drivers ​

ClassFileConstructor
RedisSetDriversrc/Driver/RedisSetDriver.php(Redis $redis, string $key = 'hermes', int $refreshInterval = 1, string $scheduleKey = 'hermes_schedule')
PredisSetDriversrc/Driver/PredisSetDriver.php(Client $redis, string $key = 'hermes', int $refreshInterval = 1, string $scheduleKey = 'hermes_schedule')
LazyRabbitMqDriversrc/Driver/LazyRabbitMqDriver.php(AbstractConnection $connection, string $queue, array $amqpMessageProperties = [], int $refreshInterval = 0, string $consumerTag = 'hermes', bool $durable = true)
AmazonSqsDriversrc/Driver/AmazonSqsDriver.php(SqsClient $client, string $queueName, array $queueAttributes = [])

RedisSetDriver::setupPriorityQueue and PredisSetDriver::setupPriorityQueue store $name at $priority. The other two always throw NotSupportedException and declare the never return type.

All four use MaxItemsTrait, ShutdownTrait, and SerializerAwareTrait.

Traits ​

src/Driver/MaxItemsTrait.php

MethodBehavior
setMaxProcessItems(int $count): void0 means no limit.
incrementProcessedItems(): intIncrements and returns the count.
processed(): intCurrent count, starting at 0.
shouldProcessNext(): boolfalse once processed >= max and max is not 0.

src/Driver/ShutdownTrait.php

MethodBehavior
setShutdown(ShutdownInterface $shutdown): voidStores it and a new DateTimeImmutable start.

shouldShutdown() and checkShutdown() are private. checkShutdown() throws ShutdownException with an empty message.

src/Driver/SerializerAwareTrait.php

MethodBehavior
setSerializer(SerializerInterface $serializer): voidReplaces the serializer.

Exceptions ​

ClassExtendsWhen
HermesException\ExceptionBase type.
SerializeExceptionHermesExceptionJSON encode or decode failed. The message never contains the serialized string, only the reason, its length and a SHA-256 prefix.
Shutdown\ShutdownExceptionHermesExceptionA shutdown check asked the worker to stop.
Driver\UnknownPriorityExceptionHermesExceptionsend() or wait() used an integer that setupPriorityQueue() never stored. Message: Unknown priority <n>.
Driver\NotSupportedExceptionHermesExceptionPriority queues on RabbitMQ or SQS.

Tomaj\Hermes\SerializerInterface ​

src/SerializerInterface.php.

php
public function serialize(MessageInterface $message): string;

public function unserialize(string $string): MessageInterface;

Both may throw SerializeException.

Tomaj\Hermes\MessageSerializer ​

src/MessageSerializer.php. Default serializer constructed by every built-in driver.

serialize() JSON-encodes message.id, message.type, message.created, message.payload, message.execute_at, and message.retries, with JSON_INVALID_UTF8_IGNORE.

unserialize() requires an array with a message object that has type, id, and created. execute_at is used when it is numeric. retries is used when it is numeric, otherwise 0. payload is used when it is an array, otherwise null. The return value is a Message. Otherwise it throws SerializeException with the reason, the length and substr(hash('sha256', $string), 0, 16): Cannot unserialize message: invalid JSON (<error>), Cannot unserialize message: no "message" key, Invalid message format: "message" needs type, id and created or Invalid message format: type and id must be strings and created a number. Invalid JSON keeps the JsonException as previous.

Tomaj\Hermes\Handler\HandlerInterface ​

src/Handler/HandlerInterface.php.

php
public function handle(MessageInterface $message): bool;

The docblock allows the method to throw \Exception.

Tomaj\Hermes\Handler\RetryableHandlerInterface ​

src/Handler/RetryableHandlerInterface.php. Extends HandlerInterface.

MethodMeaning
canRetry(MessageInterface $message, Throwable $exception): boolCalled after handle() threw, while getRetries() < maxRetry(). false skips the retry.
maxRetry(): intThe most retries a message gets. 0 turns retries off.

Tomaj\Hermes\Handler\RetryTrait ​

src/Handler/RetryTrait.php. Implements the methods of RetryableHandlerInterface. Dispatcher also retries a handler that uses the trait without declaring the interface.

MethodReturns
canRetry(MessageInterface $message, Throwable $exception): booltrue.
maxRetry(): int25. A new attempt is sent when getRetries() < maxRetry().

Tomaj\Hermes\Handler\EchoHandler ​

src/Handler/EchoHandler.php. Uses RetryTrait.

handle() echoes Received message: #<id> (type <type>) and Payload: <json>, then returns true.

Shutdown ​

src/Shutdown/ShutdownInterface.php

php
public function shouldShutdown(DateTimeInterface $startTime): bool;

public function shutdown(?DateTimeInterface $shutdownTime = null): bool;
ClassConstructorSignal
SharedFileShutdown(string $filePath)Writes the time with microseconds; touch also works. Stops when the time is later than start and not in the future.
RedisShutdown(Redis $redis, string $key = 'hermes_shutdown')SETs the time with microseconds. Stops when the value is set, not in the future, and later than start.
PredisShutdown(Client $redis, string $key = 'hermes_shutdown')Same rules. shutdown() is true when the Predis payload is OK.

Details and the differences between the file and Redis rules are on Shutdown and max items.

FAQ ​

Where is the priority argument? ​

On Emitter::emit() and DriverInterface::send(), as the second argument. Message has no priority.

Which methods can throw UnknownPriorityException? ​

send() and wait() on the Redis drivers, when a priority was not registered with setupPriorityQueue().

Is Dispatcher::emit() still supported? ​

It works but is deprecated. Use Emitter.

Which traits do the built-in drivers use? ​

MaxItemsTrait, ShutdownTrait, and SerializerAwareTrait, on all four.

Where are complete usage examples? ​

In the Examples section and in examples/ in the repository.

Released under the MIT License.