A simple worker implementation to loop a callback function until one of the defined conditions is met
composer require piotrek-r/worker
$worker = new \PiotrekR\Worker\Worker();
$worker->run(function () {
// do something
});
The callback function should return a truthy value if it did some work, and a falsy value otherwise. This is used to determine stop conditions and sleep time.
WorkerConditions
can be used to set conditions for the worker to stop.
You can set a time limit in seconds.
$workerConditions = new \PiotrekR\Worker\WorkerConditions(
timeSeconds: 10,
);
$worker = new \PiotrekR\Worker\Worker($workerConditions);
$worker->run(function () {
// do something
});
You can set a memory limit in bytes as int or as a string with a unit suffix. Supported units are: b
, k
, m
, g
, t
, p
, e
, z
, y
. It uses memory_get_usage(true)
to determine the current memory usage.
$workerConditions = new \PiotrekR\Worker\WorkerConditions(
memoryLimit: '512m',
);
$worker = new \PiotrekR\Worker\Worker($workerConditions);
$worker->run(function () {
// do something
});
You can set a loop limit. It will stop the worker after the given number of loops.
There are three different types of loop limits:
countLoops
- the number of loops which is the sum of the other typescountHandled
- the number of loops were the function returned a truthy valuecountEmpty
- the number of loops were the function returned a falsy value
To only make 100 loops no matter the result:
$workerConditions = new \PiotrekR\Worker\WorkerConditions(
countLoops: 100,
);
To only run 5 times when the function returns true
and loop infinitely when it returns false
:
$workerConditions = new \PiotrekR\Worker\WorkerConditions(
countHandled: 5,
);
To run infinitely and stop after the first time the function returns false
(e.g. when draining a queue, it will run until the queue is empty):
$workerConditions = new \PiotrekR\Worker\WorkerConditions(
countEmpty: 1,
);
You can set the sleep time in microseconds. It will sleep after each loop. You can set separate values for sleep time after a loop with a truthy value and a falsy value.
$workerConfiguration = new \PiotrekR\Worker\WorkerConfiguration(
sleepMicrosecondsAfterHandled: 1000, // 1ms to get quick to the next item
sleepMicrosecondsAfterEmpty: 5000000, // 5s to not spam the queue
);
$worker = new \PiotrekR\Worker\Worker(null, $workerConfiguration);
$worker->run(function () {
// do something
});
You can pass arguments to the run
method. All arguments will be passed to the callback function.
$arg1 = 'foo';
$arg2 = 'bar';
$arg3 = 3;
$worker = new \PiotrekR\Worker\Worker();
$worker->run(function (string $arg1, string $arg2, int $arg3) {
echo $argument;
return true;
}, $arg1, $arg2, $arg3);
The run
method returns a WorkerResult
object with the following methods:
getTimeElapsed(): int
- the time elapsed in secondsgetCountLoops(): int
- the number of loops which is the sum of the other typesgetCountHandled(): int
- the number of loops were the function returned a truthy valuegetCountEmpty(): int
- the number of loops were the function returned a falsy value
use PiotrekR\Worker\Worker;
use PiotrekR\Worker\WorkerConditions;
use PiotrekR\Worker\WorkerConfiguration;
$queue = new ThirdPartyQueueHandler();
$workerConditions = new WorkerConditions(
timeSeconds: 10,
memory: '512m',
);
$workerConfiguration = new WorkerConfiguration(
sleepMicrosecondsAfterHandled: 1000,
sleepMicrosecondsAfterEmpty: 1000000,
);
$worker = new Worker($workerConditions, $workerConfiguration);
$result = $worker->run(function (ThirdPartyQueueHandler $queue) {
return $queue->handleNextMessage();
}, $queue);
printf(
"It took %d seconds to loop %d times. Of which %d were handled, and %d were empty.\n",
$result->getTimeElapsed(),
$result->getCountLoops(),
$result->getCountHandled(),
$result->getCountEmpty(),
);