{"id":19861256,"url":"https://github.com/rybakit/phive-queue","last_synced_at":"2025-04-06T03:07:32.154Z","repository":{"id":3176125,"uuid":"4207617","full_name":"rybakit/phive-queue","owner":"rybakit","description":"$queue-\u003epush('I can be popped off after', '10 minutes');","archived":false,"fork":false,"pushed_at":"2020-12-08T14:28:05.000Z","size":532,"stargazers_count":165,"open_issues_count":9,"forks_count":10,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-30T01:13:14.486Z","etag":null,"topics":["beanstalkd","mongodb","pdo","php","queue","redis","scheduler","sysv","tarantool"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rybakit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["rybakit"]}},"created_at":"2012-05-02T21:03:48.000Z","updated_at":"2025-02-13T19:52:25.000Z","dependencies_parsed_at":"2022-09-18T01:45:10.937Z","dependency_job_id":null,"html_url":"https://github.com/rybakit/phive-queue","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybakit%2Fphive-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybakit%2Fphive-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybakit%2Fphive-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybakit%2Fphive-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rybakit","download_url":"https://codeload.github.com/rybakit/phive-queue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247427006,"owners_count":20937201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beanstalkd","mongodb","pdo","php","queue","redis","scheduler","sysv","tarantool"],"created_at":"2024-11-12T15:08:29.835Z","updated_at":"2025-04-06T03:07:32.137Z","avatar_url":"https://github.com/rybakit.png","language":"PHP","readme":"Phive Queue\n===========\n[![Build Status](https://secure.travis-ci.org/rybakit/phive-queue.svg?branch=master)](http://travis-ci.org/rybakit/phive-queue)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/rybakit/phive-queue/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/rybakit/phive-queue/?branch=master)\n[![Code Coverage](https://scrutinizer-ci.com/g/rybakit/phive-queue/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/rybakit/phive-queue/?branch=master)\n\nPhive Queue is a time-based scheduling queue with multiple backend support.\n\n\n## Table of contents\n\n * [Installation](#installation)\n * [Usage example](#usage-example)\n * [Queues](#queues)\n    * [MongoQueue](#mongoqueue)\n    * [RedisQueue](#redisqueue)\n    * [TarantoolQueue](#tarantoolqueue)\n    * [PheanstalkQueue](#pheanstalkqueue)\n    * [GenericPdoQueue](#genericpdoqueue)\n    * [SqlitePdoQueue](#sqlitepdoqueue)\n    * [SysVQueue](#sysvqueue)\n    * [InMemoryQueue](#inmemoryqueue)\n * [Item types](#item-types)\n * [Exceptions](#exceptions)\n * [Tests](#tests)\n    * [Performance](#performance)\n    * [Concurrency](#concurrency)\n * [License](#license)\n\n\n## Installation\n\nThe recommended way to install Phive Queue is through [Composer](http://getcomposer.org):\n\n```sh\n$ composer require rybakit/phive-queue\n```\n\n\n## Usage example\n\n```php\nuse Phive\\Queue\\InMemoryQueue;\nuse Phive\\Queue\\NoItemAvailableException;\n\n$queue = new InMemoryQueue();\n\n$queue-\u003epush('item1');\n$queue-\u003epush('item2', new DateTime());\n$queue-\u003epush('item3', time());\n$queue-\u003epush('item4', '+5 seconds');\n$queue-\u003epush('item5', 'next Monday');\n\n// get the queue size\n$count = $queue-\u003ecount(); // 5\n\n// pop items off the queue\n// note that is not guaranteed that the items with the same scheduled time\n// will be received in the same order in which they were added\n$item123 = $queue-\u003epop();\n$item123 = $queue-\u003epop();\n$item123 = $queue-\u003epop();\n\ntry {\n    $item4 = $queue-\u003epop();\n} catch (NoItemAvailableException $e) {\n    // item4 is not yet available\n}\n\nsleep(5);\n$item4 = $queue-\u003epop();\n\n// clear the queue (will remove 'item5')\n$queue-\u003eclear();\n```\n\n\n## Queues\n\nCurrently, there are the following queues available:\n\n * [MongoQueue](#mongoqueue)\n * [RedisQueue](#redisqueue)\n * [TarantoolQueue](#tarantoolqueue)\n * [PheanstalkQueue](#pheanstalkqueue)\n * [GenericPdoQueue](#genericpdoqueue)\n * [SqlitePdoQueue](#sqlitepdoqueue)\n * [SysVQueue](#sysvqueue)\n * [InMemoryQueue](#inmemoryqueue)\n\n#### MongoQueue\n\nThe `MongoQueue` requires the [Mongo PECL](http://pecl.php.net/package/mongo) extension *(v1.3.0 or higher)*.\n\n\n*Tip:* Before making use of the queue, it's highly recommended to create an index on a `eta` field:\n\n```sh\n$ mongo my_db --eval 'db.my_coll.ensureIndex({ eta: 1 })'\n```\n\n##### Constructor\n\n```php\npublic MongoQueue::__construct(MongoClient $mongoClient, string $dbName, string $collName)\n```\n\nParameters:\n\n\u003e \u003cb\u003emongoClient\u003c/b\u003e    The MongoClient instance\u003cbr\u003e\n\u003e \u003cb\u003edbName\u003c/b\u003e         The database name\u003cbr\u003e\n\u003e \u003cb\u003ecollName\u003c/b\u003e       The collection name\u003cbr\u003e\n\n##### Example\n\n```php\nuse Phive\\Queue\\MongoQueue;\n\n$client = new MongoClient();\n$queue = new MongoQueue($client, 'my_db', 'my_coll');\n```\n\n#### RedisQueue\n\nFor the `RedisQueue` you have to install the [Redis PECL](http://pecl.php.net/package/redis) extension *(v2.2.3 or higher)*.\n\n##### Constructor\n\n```php\npublic RedisQueue::__construct(Redis $redis)\n```\n\nParameters:\n\n\u003e \u003cb\u003eredis\u003c/b\u003e The Redis instance\u003cbr\u003e\n\n##### Example\n\n```php\nuse Phive\\Queue\\RedisQueue;\n\n$redis = new Redis();\n$redis-\u003econnect('127.0.0.1');\n$redis-\u003esetOption(Redis::OPT_PREFIX, 'my_prefix:');\n\n// Since the Redis client v2.2.5 the RedisQueue has the ability to utilize serialization:\n// $redis-\u003esetOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);\n\n$queue = new RedisQueue($redis);\n```\n\n#### TarantoolQueue\n\nTo use the `TarantoolQueue` you have to install the [Tarantool PECL](https://github.com/tarantool/tarantool-php)\nextension and a [Lua script](https://github.com/tarantool/queue) for managing queues.\n\n##### Constructor\n\n```php\npublic TarantoolQueue::__construct(Tarantool $tarantool, string $tubeName [, int $space = null ])\n```\n\nParameters:\n\n\u003e \u003cb\u003etarantool\u003c/b\u003e  The Tarantool instance\u003cbr\u003e\n\u003e \u003cb\u003etubeName\u003c/b\u003e   The tube name\u003cbr\u003e\n\u003e \u003cb\u003espace\u003c/b\u003e      \u003ci\u003eOptional\u003c/i\u003e. The space number. Default to 0\n\n##### Example\n\n```php\nuse Phive\\Queue\\TarantoolQueue;\n\n$tarantool = new Tarantool('127.0.0.1', 33020);\n$queue = new TarantoolQueue($tarantool, 'my_tube');\n```\n\n#### PheanstalkQueue\n\nThe `PheanstalkQueue` requires the [Pheanstalk](https://github.com/pda/pheanstalk)\nlibrary ([Beanstalk](http://kr.github.io/beanstalkd) client) to be installed:\n\n```sh\n$ composer require pda/pheanstalk:~3.0\n```\n\n##### Constructor\n\n```php\npublic PheanstalkQueue::__construct(Pheanstalk\\PheanstalkInterface $pheanstalk, string $tubeName)\n```\n\nParameters:\n\n\u003e \u003cb\u003epheanstalk\u003c/b\u003e The Pheanstalk\\PheanstalkInterface instance\u003cbr\u003e\n\u003e \u003cb\u003etubeName\u003c/b\u003e   The tube name\u003cbr\u003e\n\n##### Example\n\n```php\nuse Pheanstalk\\Pheanstalk;\nuse Phive\\Queue\\PheanstalkQueue;\n\n$pheanstalk = new Pheanstalk('127.0.0.1');\n$queue = new PheanstalkQueue($pheanstalk, 'my_tube');\n```\n\n#### GenericPdoQueue\n\nThe `GenericPdoQueue` is intended for PDO drivers whose databases support stored procedures/functions\n(in fact all drivers except SQLite).\n\nThe `GenericPdoQueue` requires [PDO](http://php.net/pdo) and a [PDO driver](http://php.net/manual/en/pdo.drivers.php)\nfor a particular database be installed. On top of that PDO error mode must be set to throw\nexceptions (`PDO::ERRMODE_EXCEPTION`).\n\nSQL files to create the table and the stored routine can be found in the [res](res) directory.\n\n##### Constructor\n\n```php\npublic GenericPdoQueue::__construct(PDO $pdo, string $tableName [, string $routineName = null ] )\n```\n\nParameters:\n\n\u003e \u003cb\u003epdo\u003c/b\u003e         The PDO instance\u003cbr\u003e\n\u003e \u003cb\u003etableName\u003c/b\u003e   The table name\u003cbr\u003e\n\u003e \u003cb\u003eroutineName\u003c/b\u003e \u003ci\u003eOptional\u003c/i\u003e. The routine name. Default to \u003cb\u003etableName\u003c/b\u003e_pop\u003cbr\u003e\n\n##### Example\n\n```php\nuse Phive\\Queue\\Pdo\\GenericPdoQueue;\n\n$pdo = new PDO('pgsql:host=127.0.0.1;port=5432;dbname=my_db', 'db_user', 'db_pass');\n$pdo-\u003esetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n\n$queue = new GenericPdoQueue($pdo, 'my_table', 'my_routine');\n```\n\n#### SqlitePdoQueue\n\nThe `SqlitePdoQueue` requires [PDO](http://php.net/pdo) and [SQLite PDO driver](http://php.net/manual/en/ref.pdo-sqlite.php).\nOn top of that PDO error mode must be set to throw exceptions (`PDO::ERRMODE_EXCEPTION`).\n\nSQL file to create the table can be found in the [res/sqlite](res/sqlite) directory.\n\n*Tip:* For performance reasons it's highly recommended to activate [WAL mode](http://www.sqlite.org/wal.html):\n\n```php\n$pdo-\u003eexec('PRAGMA journal_mode=WAL');\n```\n\n##### Constructor\n\n```php\npublic SqlitePdoQueue::__construct(PDO $pdo, string $tableName)\n```\n\nParameters:\n\n\u003e \u003cb\u003epdo\u003c/b\u003e       The PDO instance\u003cbr\u003e\n\u003e \u003cb\u003etableName\u003c/b\u003e The table name\u003cbr\u003e\n\n##### Example\n\n```php\nuse Phive\\Queue\\Pdo\\SqlitePdoQueue;\n\n$pdo = new PDO('sqlite:/opt/databases/my_db.sq3');\n$pdo-\u003esetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n$pdo-\u003eexec('PRAGMA journal_mode=WAL');\n\n$queue = new SqlitePdoQueue($pdo, 'my_table');\n```\n\n#### SysVQueue\n\nThe `SysVQueue` requires PHP to be compiled with the option **--enable-sysvmsg**.\n\n##### Constructor\n\n```php\npublic SysVQueue::__construct(int $key [, bool $serialize = null [, int $perms = null ]] )\n```\n\nParameters:\n\n\u003e \u003cb\u003ekey\u003c/b\u003e       The message queue numeric ID\u003cbr\u003e\n\u003e \u003cb\u003eserialize\u003c/b\u003e \u003ci\u003eOptional\u003c/i\u003e. Whether to serialize an item or not. Default to false\u003cbr\u003e\n\u003e \u003cb\u003eperms\u003c/b\u003e     \u003ci\u003eOptional\u003c/i\u003e. The queue permissions. Default to 0666\u003cbr\u003e\n\n##### Example\n\n```php\nuse Phive\\Queue\\SysVQueue;\n\n$queue = new SysVQueue(123456);\n```\n\n#### InMemoryQueue\n\nThe `InMemoryQueue` can be useful in cases where the persistence is not needed. It exists only in RAM\nand therefore operates faster than other queues.\n\n##### Constructor\n\n```php\npublic InMemoryQueue::__construct()\n```\n\n##### Example\n\n```php\nuse Phive\\Queue\\InMemoryQueue;\n\n$queue = new InMemoryQueue();\n```\n\n\n## Item types\n\nThe following table details the various item types supported across queues.\n\n|              Queue/Type               | string  | binary string |  null   |  bool   |   int   |  float  |  array  | object  |\n|---------------------------------------|:-------:|:-------------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|\n| [MongoQueue](#mongoqueue)             |    ✓    |               |    ✓    |    ✓    |    ✓    |    ✓    |    ✓    |         |\n| [RedisQueue](#redisqueue)             |    ✓    |       ✓       |    ✓    |    ✓    |    ✓    |    ✓    |    ✓*   |    ✓*   |\n| [TarantoolQueue](#tarantoolqueue)     |    ✓    |       ✓       |    ✓    |    ✓    |    ✓    |    ✓    |         |         |\n| [PheanstalkQueue](#pheanstalkqueue)   |    ✓    |       ✓       |    ✓    |    ✓    |    ✓    |    ✓    |         |         |\n| [GenericPdoQueue](#genericpdoqueue)   |    ✓    |               |    ✓    |    ✓    |    ✓    |    ✓    |         |         |\n| [SqlitePdoQueue](#sqlitepdoqueue)     |    ✓    |               |    ✓    |    ✓    |    ✓    |    ✓    |         |         |\n| [SysVQueue](#sysvqueue)               |    ✓    |       ✓       |    ✓*   |    ✓    |    ✓    |    ✓    |    ✓*   |    ✓*   |\n| [InMemoryQueue](#inmemoryqueue)       |    ✓    |       ✓       |    ✓    |    ✓    |    ✓    |    ✓    |    ✓    |    ✓    |\n\n\u003e ✓*  — supported if the serializer is enabled.\n\nTo bypass the limitation of unsupported types for the particular queue you could convert an item\nto a non-binary string before pushing it and then back after popping. The library ships with\nthe `TypeSafeQueue` decorator which does that for you:\n\n```php\nuse Phive\\Queue\\GenericPdoQueue;\nuse Phive\\Queue\\TypeSafeQueue;\n\n$queue = new GenericPdoQueue(...);\n$queue = new TypeSafeQueue($queue);\n\n$queue-\u003epush(['foo' =\u003e 'bar']);\n$array = $queue-\u003epop(); // ['foo' =\u003e 'bar'];\n```\n\n\n## Exceptions\n\nEvery queue method declared in the [Queue](src/Queue.php) interface will throw an exception\nif a run-time error occurs at the time the method is called.\n\nFor example, in the code below, the `push()` call will fail with a `MongoConnectionException`\nexception in a case a remote server unreachable:\n\n```php\nuse Phive\\Queue\\MongoQueue;\n\n$queue = new MongoQueue(...);\n\n// mongodb server goes down here\n\n$queue-\u003epush('item'); // throws MongoConnectionException\n```\n\nBut sometimes you may want to catch exceptions coming from a queue regardless of the underlying driver.\nTo do this just wrap your queue object with the `ExceptionalQueue` decorator:\n\n```php\nuse Phive\\Queue\\ExceptionalQueue;\nuse Phive\\Queue\\MongoQueue;\n\n$queue = new MongoQueue(...);\n$queue = new ExceptionalQueue($queue);\n\n// mongodb server goes down here\n\n$queue-\u003epush('item'); // throws Phive\\Queue\\QueueException\n```\n\nAnd then, to catch queue level exceptions use the `QueueException` class:\n\n```php\nuse Phive\\Queue\\QueueException;\n\n...\n\ntry {\n    do_something_with_a_queue();\n} catch (QueueException $e) {\n    // handle queue exception\n} catch (\\Exception $e) {\n    // handle base exception\n}\n```\n\n\n## Tests\n\nPhive Queue uses [PHPUnit](http://phpunit.de) for unit and integration testing.\nIn order to run the tests, you'll first need to install the library dependencies using composer:\n\n```sh\n$ composer install\n```\n\nYou can then run the tests:\n\n```sh\n$ phpunit\n```\n\nYou may also wish to specify your own default values of some tests (db names, passwords, queue sizes, etc.).\nYou can do it by setting environment variables from the command line:\n\n```sh\n$ export PHIVE_PDO_PGSQL_PASSWORD=\"pgsql_password\"\n$ export PHIVE_PDO_MYSQL_PASSWORD=\"mysql_password\"\n$ phpunit\n```\n\nYou may also create your own `phpunit.xml` file by copying the [phpunit.xml.dist](phpunit.xml.dist)\nfile and customize to your needs.\n\n\n#### Performance\n\nTo check the performance of queues run:\n\n```sh\n$ phpunit --group performance\n```\n\nThis test inserts a number of items (1000 by default) into a queue, and then retrieves them back.\nIt measures the average time for `push` and `pop` operations and outputs the resulting stats, e.g.:\n\n```sh\nRedisQueue::push()\n   Total operations:      1000\n   Operations per second: 14031.762 [#/sec]\n   Time per operation:    71.267 [ms]\n   Time taken for test:   0.071 [sec]\n\nRedisQueue::pop()\n   Total operations:      1000\n   Operations per second: 16869.390 [#/sec]\n   Time per operation:    59.279 [ms]\n   Time taken for test:   0.059 [sec]\n.\nRedisQueue::push() (delayed)\n   Total operations:      1000\n   Operations per second: 15106.226 [#/sec]\n   Time per operation:    66.198 [ms]\n   Time taken for test:   0.066 [sec]\n\nRedisQueue::pop() (delayed)\n   Total operations:      1000\n   Operations per second: 14096.416 [#/sec]\n   Time per operation:    70.940 [ms]\n   Time taken for test:   0.071 [sec]\n```\n\nYou may also change the number of items involved in the test by changing the `PHIVE_PERF_QUEUE_SIZE`\nvalue in your `phpunit.xml` file or by setting the environment variable from the command line:\n\n```sh\n$ PHIVE_PERF_QUEUE_SIZE=5000 phpunit --group performance\n```\n\n\n#### Concurrency\n\nIn order to check the concurrency you'll have to install the [Gearman](http://gearman.org) server\nand the [German PECL](http://pecl.php.net/package/gearman) extension.\nOnce the server has been installed and started, create a number of processes (workers) by running:\n\n```sh\n$ php tests/worker.php\n```\n\nThen run the tests:\n\n```sh\n$ phpunit --group concurrency\n```\n\nThis test inserts a number of items (100 by default) into a queue, and then each worker tries\nto retrieve them in parallel.\n\nYou may also change the number of items involved in the test by changing the `PHIVE_CONCUR_QUEUE_SIZE`\nvalue in your `phpunit.xml` file or by setting the environment variable from the command line:\n\n```sh\n$ PHIVE_CONCUR_QUEUE_SIZE=500 phpunit --group concurrency\n```\n\n\n## License\n\nPhive Queue is released under the MIT License. See the bundled [LICENSE](LICENSE) file for details.\n","funding_links":["https://github.com/sponsors/rybakit"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frybakit%2Fphive-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frybakit%2Fphive-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frybakit%2Fphive-queue/lists"}