{"id":15154480,"url":"https://github.com/willry/mongo-queue","last_synced_at":"2026-01-20T11:32:13.714Z","repository":{"id":62549250,"uuid":"487141669","full_name":"WillRy/mongo-queue","owner":"WillRy","description":"Um gerenciador de filas com MongoDB, permitindo o uso de workers e número de tentativas de processamento em caso de erro","archived":false,"fork":false,"pushed_at":"2022-09-13T03:44:37.000Z","size":41,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-13T14:42:05.002Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WillRy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-30T00:06:14.000Z","updated_at":"2022-04-30T00:07:38.000Z","dependencies_parsed_at":"2022-11-03T01:15:31.885Z","dependency_job_id":null,"html_url":"https://github.com/WillRy/mongo-queue","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillRy%2Fmongo-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillRy%2Fmongo-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillRy%2Fmongo-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillRy%2Fmongo-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WillRy","download_url":"https://codeload.github.com/WillRy/mongo-queue/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247648910,"owners_count":20972944,"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":[],"created_at":"2024-09-26T17:40:34.949Z","updated_at":"2026-01-20T11:32:13.709Z","avatar_url":"https://github.com/WillRy.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mongo Queue\n\nUma biblioteca para criar filas e background jobs usando mongodb.\n\nA biblioteca permite:\n\n- Criação de multiplas filas\n- Uso de vários workers (workers não pegam itens duplicados)\n- Ao usar mongo como fila, ao invés do REDIS, é possível realizar pesquisas indexadas no payload dos itens da fila\n\n## Performance\n\nEm testes realizados foi possível manter 600.000 itens na fila, com 9 workers processando com um delay de 2s no consumo,\ncom menos de 2.5% de CPU.\n\n## Utilização\n\nA pasta **demo** contém demonstrações de como **publicar**, **consumir** e **excluir** itens velhos\n\n### Publicar item na fila\n\n```php\n\u003c?php\n\nrequire __DIR__ . \"/../vendor/autoload.php\";\n\nuse WillRy\\MongoQueue\\Connect;\n\nConnect::config(\"mongo\", \"root\", \"root\");\n\n/** @var bool Indica se é para excluir item da fila ao finalizar todo o ciclo de processamento */\n$autoDelete = true;\n\n/** @var int|null Número máximo de retentativa caso tenha recolocar fila configurado */\n$maxRetries = 3;\n\n/** @var bool Se deve recolocar na fila em caso de erro */\n$requeue_on_error = true;\n\n/** @var int Tempo em minutos que um item fica invisivel na fila, para não ser reprocessado */\n$visibilityMinutes = 1;\n\n/** @var int Delay em segundos para o processamento de cada item */\n$delaySeconds = 3;\n\n$mqueue = new \\WillRy\\MongoQueue\\Queue(\n    \"queue_database\",\n    \"queue_list\",\n    $autoDelete,\n    $visibilityMinutes\n);\n\n$id = rand();\nfor ($i = 0; $i \u003c=2;$i++){\n    $mqueue-\u003einsert($i, [\n        'id' =\u003e $i,\n        \"name\" =\u003e \"Fulano {$i}\",\n        \"description\" =\u003e \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum semper ex in odio convallis, id dapibus ante ullamcorper. Nulla aliquet risus sapien, nec finibus mi pharetra ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas non sollicitudin lacus, sit amet volutpat sapien. Aliquam erat volutpat. Pellentesque suscipit venenatis rutrum.\",\n        \"email\" =\u003e \"fulano{$i}@teste.com\"\n    ], $requeue_on_error, $maxRetries);\n}\n\n```\n\n### Consumir item na fila\n\n**Criar classe que processa o item na fila**\n\n```php\n\u003c?php\n\nclass WorkerQueue implements \\WillRy\\MongoQueue\\WorkerInterface\n{\n\n    public function handle(\\WillRy\\MongoQueue\\Task $task)\n    {\n        $parImpar = rand() % 2 === 0;\n\n        //if is too long, made a ping\n        if($parImpar) $task-\u003eping();\n\n        //fake error = Exceptions são detectadas e tratadas como nackError automaticamente\n        IF($parImpar) throw new Exception(\"Erro aleatório\");\n\n\n        $task-\u003eack(); //marca como sucesso\n\n        /** marca como erro */\n        //$task-\u003enackError();\n\n        /** marca como cancelado */\n//        $task-\u003enackCanceled();\n\n\n    }\n\n    public function error($data = null, \\Exception $error = null)\n    {\n\n    }\n}\n\n```\n\n**Arquivo que consome a fila com a classe de worker**\n```php\n\u003c?php\n\nuse WillRy\\MongoQueue\\Connect;\n\nrequire_once __DIR__ . \"/../vendor/autoload.php\";\nrequire_once __DIR__ . \"/WorkerQueue.php\";\n\nConnect::config(\"mongo\", \"root\", \"root\");\n\n\n/** @var bool Indica se é para excluir item da fila ao finalizar todo o ciclo de processamento */\n$autoDelete = false;\n\n/** @var int Tempo em minutos que um item fica invisivel na fila, para não ser reprocessado */\n$visibilityMinutes = 1;\n\n/** @var int Delay em segundos para o processamento de cada item */\n$delaySeconds = 3;\n\n$mqueue = new \\WillRy\\MongoQueue\\Queue(\n    \"queue_database\",\n    \"queue_list\",\n    $autoDelete,\n    $visibilityMinutes\n);\n$worker = new WorkerQueue();\n\n\n/** Consumir um item por vez, recomendado para crons */\n//$mqueue-\u003econsume($worker);\n\n/** Consumir através de um loop (recomendado para supervisor e systemd) */\n$mqueue-\u003econsumeLoop($worker, $delaySeconds);\n```\n\n### Excluir item específico da fila\n\nExcluir item da fila com base no ID\n\n```php\n\u003c?php\n\nrequire_once __DIR__ . \"/../vendor/autoload.php\";\n\nuse WillRy\\MongoQueue\\Connect;\nConnect::config(\"mongo\", \"root\", \"root\");\n\n$autoDelete = false;\n$maxRetries = 3;\n$visibilityMinutes = 1;\n\n$mqueue = new \\WillRy\\MongoQueue\\Queue(\n    \"queue_database\",\n    \"queue_list\",\n    $autoDelete,\n    $maxRetries,\n    $visibilityMinutes\n);\n\n/**\n * Delete job by id\n */\n$mqueue-\u003edeleteJobByCustomID(1);\n```\n\n### Excluir item antigo na fila\n\nExcluir itens processados em \"N\" dias atrás\n\n```php\n\u003c?php\n\nrequire_once __DIR__ . \"/../vendor/autoload.php\";\n\nuse WillRy\\MongoQueue\\Connect;\nConnect::config(\"mongo\", \"root\", \"root\");\n\n$autoDelete = false;\n$maxRetries = 3;\n$visibilityMinutes = 1;\n\n$mqueue = new \\WillRy\\MongoQueue\\Queue(\n    \"queue_database\",\n    \"queue_list\",\n    $autoDelete,\n    $maxRetries,\n    $visibilityMinutes\n);\n\n/**\n * Delete job by id\n */\n$mqueue-\u003edeleteJobByCustomID(1);\n```\n\n### Usar conexão do mongo\n\n```php\n\u003c?php\n\nrequire_once __DIR__ . \"/../vendor/autoload.php\";\n\n/** @var bool Indica se é para excluir item da fila ao finalizar todo o ciclo de processamento */\n$autoDelete = true;\n\n/** @var int|null Número máximo de retentativa caso tenha recolocar fila configurado */\n$maxRetries = 3;\n\n/** @var int Tempo em minutos que um item fica invisivel na fila, para não ser reprocessado */\n$visibilityMinutes = 1;\n\n/** @var int Delay em segundos para o processamento de cada item */\n$delaySeconds = 3;\n\n$mqueue = new \\WillRy\\MongoQueue\\Queue(\n    \"queue\",\n    \"list\",\n    $autoDelete,\n    $maxRetries,\n    $visibilityMinutes\n);\n\n/** @var MongoDB\\Client|null  */\n$connection = $mqueue-\u003edb;\n```\n\n### Criar indices para pesquisa na fila\n\nPara pesquisar itens na fila, com base em algum campo do payload, é possível criar um indice e em seguida usar o método\nde pesquisa.\n\n**IMPORTANTE**\n\nDeve criar os indices com base na ordem em que os campos são usados na pesquisa\n\n```php\n\u003c?php\n\n\nrequire_once __DIR__ . \"/../vendor/autoload.php\";\n\nuse WillRy\\MongoQueue\\Connect;\nConnect::config(\"mongo\", \"root\", \"root\");\n\n$autoDelete = false;\n$requeue = true;\n$maxRetries = 3;\n$visibilityMinutes = 1;\n\n$mqueue = new \\WillRy\\MongoQueue\\Queue(\n    \"queue\",\n    \"list\",\n    $autoDelete,\n    $maxRetries,\n    $visibilityMinutes\n);\n\nfor ($i = 0; $i \u003c= 10; $i++) {\n    $mqueue-\u003einsert($i, [\n        'id' =\u003e $i,\n        \"name\" =\u003e \"Fulano {$i}\"\n    ]);\n}\n\n$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_NUMBER_INT) ?? 1;\n\n/** filtrar itens não processados que contenham o nome \"fulano\" no payload  */\n$filter = [\n    \"startTime\" =\u003e null,\n    \"payload.name\" =\u003e [\n        '$regex' =\u003e 'fulano', '$options' =\u003e 'i'\n    ]\n];\n$mqueue-\u003ecreateIndex([\n    \"startTime\" =\u003e 1,\n    \"payload.name\" =\u003e 1\n]);\n$cursor = $mqueue-\u003esearchByPayload(\n    $page,\n    10,\n    $filter\n);\n$total = $mqueue-\u003ecountByPayload($filter);\n\n$break = !empty($_SERVER[\"SERVER_NAME\"]) ? \"\u003cbr\u003e\" : PHP_EOL;\n\nprint(\"Total: {$total}\" . $break);\n\nforeach ($cursor as $document) {\n    $data = $document-\u003egetArrayCopy();\n    print(\"ID: {$data[\"id\"]}\" . $break);\n}\n```\n\n\n## Configurar ambiente de produção\n\nEm produção, o ideal é utilizar um supervisor para manter em execução\no processamento da fila com vários workers.\n\n### Instalar o supervisor\n\n```shell\n# instalar o supervisor\nsudo apt-get install supervisor\n```\n\n### Configurar arquivo do worker \n\nConfigurar em **/etc/supervisor/conf.d/mongo-worker.conf**\n\n```text\n[program:mongo-worker]\nprocess_name=%(program_name)s_%(process_num)02d\ncommand=php /var/www/consume.php\nautostart=true\nautorestart=true\nstopasgroup=true\nkillasgroup=true\nuser=www-data\nnumprocs=2\nredirect_stderr=true\nstdout_logfile=/var/www/worker.log\nstopwaitsecs=3600\n```\n\n**command=** O caminho do script ou comando que vai fazer o consumo\n\n**numprocs=** O número de workers\n\n### Executar supervisor\n\n```shell\nsudo supervisorctl reread\n\nsudo supervisorctl update\n\nsudo supervisorctl start mongo-worker:*\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillry%2Fmongo-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillry%2Fmongo-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillry%2Fmongo-queue/lists"}