{"id":13501288,"url":"https://github.com/allisson/fastqueue","last_synced_at":"2025-07-14T15:06:54.873Z","repository":{"id":150860091,"uuid":"528994723","full_name":"allisson/fastqueue","owner":"allisson","description":"Simple queue system based on FastAPI and PostgreSQL","archived":false,"fork":false,"pushed_at":"2023-04-26T00:55:06.000Z","size":326,"stargazers_count":49,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-06T04:09:01.008Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Python","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/allisson.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-08-25T19:40:32.000Z","updated_at":"2025-04-10T04:41:47.000Z","dependencies_parsed_at":"2024-01-16T10:35:20.619Z","dependency_job_id":"8b196e3a-d318-4995-81aa-7441fe0f08eb","html_url":"https://github.com/allisson/fastqueue","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/allisson/fastqueue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisson%2Ffastqueue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisson%2Ffastqueue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisson%2Ffastqueue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisson%2Ffastqueue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allisson","download_url":"https://codeload.github.com/allisson/fastqueue/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisson%2Ffastqueue/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265311871,"owners_count":23745161,"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":["hacktoberfest"],"created_at":"2024-07-31T22:01:31.685Z","updated_at":"2025-07-14T15:06:54.844Z","avatar_url":"https://github.com/allisson.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# fastqueue\nSimple queue system based on FastAPI and PostgreSQL.\n\n## Features\n\n- Simple rest api.\n- Message filtering support.\n- Dead queue support.\n- Redrive support (move messages between queues).\n- Delay queues support.\n- Prometheus metrics support.\n- Simplicity, it does the minimum necessary, it will not have an authentication/permission scheme among other things.\n\n## Quickstart\n\nLet's start with the basic concepts, we have three main entities that we must know to start:\n\n- Topic: A named resource to which messages are sent.\n- Queue: A named resource representing a queue that receives messages from topics.\n- Message: The data that a publisher sends to a topic is eventually delivered to queues.\n\n### Environment variables\n\nSee https://github.com/allisson/fastqueue/blob/main/env.sample.default.\n\n### Run the local PostgreSQL server\n\nTo run the server it is necessary to have a database available from PostgreSQL:\n\n```bash\ndocker run --name postgres-fastqueue \\\n    --restart unless-stopped \\\n    -e POSTGRES_USER=fastqueue \\\n    -e POSTGRES_PASSWORD=fastqueue \\\n    -e POSTGRES_DB=fastqueue \\\n    -p 5432:5432 \\\n    -d postgres:14-alpine\n```\n\n### Run the database migration\n\nThe database migration is responsible to create the database schema.\n\n```bash\ndocker run --rm \\\n    -e fastqueue_database_url='postgresql+psycopg2://fastqueue:fastqueue@localhost:5432/fastqueue' \\\n    --network=\"host\" \\\n    quay.io/allisson/fastqueue db-migrate\n```\n\n### Run the worker\n\nThe worker is responsible for cleanup the messages from queues (remove expired messages and move to dead queue if configured).\n\n```bash\ndocker run --name fastqueue-worker \\\n    --restart unless-stopped \\\n    -e fastqueue_database_url='postgresql+psycopg2://fastqueue:fastqueue@localhost:5432/fastqueue' \\\n    -e fastqueue_queue_cleanup_interval_seconds=60 \\\n    --network=\"host\" \\\n    quay.io/allisson/fastqueue worker\n```\n\n### Run the server\n\nThe server is responsible to deliver the rest API.\n\n```bash\ndocker run --name fastqueue-server \\\n    --restart unless-stopped \\\n    -e fastqueue_database_url='postgresql+psycopg2://fastqueue:fastqueue@localhost:5432/fastqueue' \\\n    -e fastqueue_server_port=8000 \\\n    -e fastqueue_server_num_workers=1 \\\n    --network=\"host\" \\\n    quay.io/allisson/fastqueue server\n```\n\nYou can access the api docs at http://localhost:8000/docs or http://localhost:8000/redoc.\n\n### Create a new topic\n\n```bash\ncurl -i -X 'POST' \\\n  'http://127.0.0.1:8000/topics' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"id\": \"events\"\n}'\n\nHTTP/1.1 201 Created\ndate: Wed, 05 Oct 2022 21:48:24 GMT\nserver: uvicorn\ncontent-length: 57\ncontent-type: application/json\n\n{\n  \"id\":\"events\",\n  \"created_at\":\"2022-10-05T21:48:24.724341\"\n}\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://127.0.0.1:8000/topics' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Wed, 05 Oct 2022 21:49:40 GMT\nserver: uvicorn\ncontent-length: 68\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"events\",\n      \"created_at\":\"2022-10-05T21:48:24.724341\"\n    }\n  ]\n}\n```\n\n### Create a new queue\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/queues' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"id\": \"all-events\",\n  \"topic_id\": \"events\",\n  \"ack_deadline_seconds\": 30,\n  \"message_retention_seconds\": 1209600\n}'\n\nHTTP/1.1 201 Created\ndate: Wed, 05 Oct 2022 21:51:43 GMT\nserver: uvicorn\ncontent-length: 259\ncontent-type: application/json\n\n{\n  \"id\":\"all-events\",\n  \"topic_id\":\"events\",\n  \"dead_queue_id\":null,\n  \"ack_deadline_seconds\":30,\n  \"message_retention_seconds\":1209600,\n  \"message_filters\":null,\n  \"message_max_deliveries\":null,\n  \"delivery_delay_seconds\":null,\n  \"created_at\":\"2022-10-05T21:51:44.684743\",\n  \"updated_at\":\"2022-10-05T21:51:44.684743\"\n}\n```\n\n### Create a new message\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/topics/events/messages' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"data\": {\"event_name\": \"event1\", \"success\": true},\n  \"attributes\": {\"event_name\": \"event1\"}\n}'\n\nHTTP/1.1 201 Created\ndate: Wed, 05 Oct 2022 21:54:07 GMT\nserver: uvicorn\ncontent-length: 355\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"147d5f58-9dc5-4f69-8ab1-107a799fd731\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"event_name\":\"event1\",\n        \"success\":true\n      },\n      \"attributes\":{\n        \"event_name\":\"event1\"\n      },\n      \"delivery_attempts\":0,\n      \"expired_at\":\"2022-10-19T21:54:08.010379\",\n      \"scheduled_at\":\"2022-10-05T21:54:08.010379\",\n      \"created_at\":\"2022-10-05T21:54:08.010379\",\n      \"updated_at\":\"2022-10-05T21:54:08.010379\"\n    }\n  ]\n}\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/stats' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Wed, 05 Oct 2022 21:55:13 GMT\nserver: uvicorn\ncontent-length: 70\ncontent-type: application/json\n\n{\n  \"num_undelivered_messages\":1,\n  \"oldest_unacked_message_age_seconds\":66\n}\n```\n\n### Consume messages from the queue\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/messages' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Wed, 05 Oct 2022 21:56:07 GMT\nserver: uvicorn\ncontent-length: 355\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"147d5f58-9dc5-4f69-8ab1-107a799fd731\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"success\":true,\n        \"event_name\":\"event1\"\n      },\n      \"attributes\":{\n        \"event_name\":\"event1\"\n      },\n      \"delivery_attempts\":1,\n      \"expired_at\":\"2022-10-19T21:54:08.010379\",\n      \"scheduled_at\":\"2022-10-05T21:56:37.272384\",\n      \"created_at\":\"2022-10-05T21:54:08.010379\",\n      \"updated_at\":\"2022-10-05T21:56:07.272384\"\n    }\n  ]\n}\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/messages/147d5f58-9dc5-4f69-8ab1-107a799fd731/nack' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 204 No Content\ndate: Wed, 05 Oct 2022 21:57:17 GMT\nserver: uvicorn\ncontent-type: application/json\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/messages' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Wed, 05 Oct 2022 21:57:53 GMT\nserver: uvicorn\ncontent-length: 355\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"147d5f58-9dc5-4f69-8ab1-107a799fd731\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"success\":true,\n        \"event_name\":\"event1\"\n      },\n      \"attributes\":{\n        \"event_name\":\"event1\"\n      },\n      \"delivery_attempts\":2,\n      \"expired_at\":\"2022-10-19T21:54:08.010379\",\n      \"scheduled_at\":\"2022-10-05T21:58:24.560500\",\n      \"created_at\":\"2022-10-05T21:54:08.010379\",\n      \"updated_at\":\"2022-10-05T21:57:54.560500\"\n    }\n  ]\n}\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/messages/147d5f58-9dc5-4f69-8ab1-107a799fd731/ack' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 204 No Content\ndate: Wed, 05 Oct 2022 21:58:56 GMT\nserver: uvicorn\ncontent-type: application/json\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/messages' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Wed, 05 Oct 2022 21:59:26 GMT\nserver: uvicorn\ncontent-length: 11\ncontent-type: application/json\n\n{\n  \"data\":[]\n}\n```\n\n## Message filtering\n\nWe can receive a subset of the messages in the queue using the message_filters field.\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/queues' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"id\": \"filtered-events\",\n  \"topic_id\": \"events\",\n  \"ack_deadline_seconds\": 30,\n  \"message_retention_seconds\": 1209600,\n  \"message_filters\": {\n    \"event_name\": [\"event2\"]\n  }\n}'\n\nHTTP/1.1 201 Created\ndate: Wed, 05 Oct 2022 23:42:09 GMT\nserver: uvicorn\ncontent-length: 285\ncontent-type: application/json\n\n{\n  \"id\":\"filtered-events\",\n  \"topic_id\":\"events\",\n  \"dead_queue_id\":null,\n  \"ack_deadline_seconds\":30,\n  \"message_retention_seconds\":1209600,\n  \"message_filters\":{\n    \"event_name\":[\n      \"event2\"\n    ]\n  },\n  \"message_max_deliveries\":null,\n  \"delivery_delay_seconds\":null,\n  \"created_at\":\"2022-10-05T23:42:10.322336\",\n  \"updated_at\":\"2022-10-05T23:42:10.322336\"\n}\n```\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/topics/events/messages' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"data\": {\"event_name\": \"event1\", \"success\": true},\n  \"attributes\": {\"event_name\": \"event1\"}\n}'\n\nHTTP/1.1 201 Created\ndate: Wed, 05 Oct 2022 23:43:33 GMT\nserver: uvicorn\ncontent-length: 355\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"1dd422ad-7d20-4257-94c0-00fc1fbb8092\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"event_name\":\"event1\",\n        \"success\":true\n      },\n      \"attributes\":{\n        \"event_name\":\"event1\"\n      },\n      \"delivery_attempts\":0,\n      \"expired_at\":\"2022-10-19T23:43:33.265369\",\n      \"scheduled_at\":\"2022-10-05T23:43:33.265369\",\n      \"created_at\":\"2022-10-05T23:43:33.265369\",\n      \"updated_at\":\"2022-10-05T23:43:33.265369\"\n    }\n  ]\n}\n```\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/topics/events/messages' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"data\": {\"event_name\": \"event2\", \"success\": true},\n  \"attributes\": {\"event_name\": \"event2\"}\n}'\n\nHTTP/1.1 201 Created\ndate: Wed, 05 Oct 2022 23:51:35 GMT\nserver: uvicorn\ncontent-length: 705\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"8856ea21-665f-40a1-b576-33fa067c6a7a\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"event_name\":\"event2\",\n        \"success\":true\n      },\n      \"attributes\":{\n        \"event_name\":\"event2\"\n      },\n      \"delivery_attempts\":0,\n      \"expired_at\":\"2022-10-19T23:51:36.175915\",\n      \"scheduled_at\":\"2022-10-05T23:51:36.175915\",\n      \"created_at\":\"2022-10-05T23:51:36.175915\",\n      \"updated_at\":\"2022-10-05T23:51:36.175915\"\n    },\n    {\n      \"id\":\"46f9b01c-2a1c-46d9-89a2-0beb2c331ae3\",\n      \"queue_id\":\"filtered-events\",\n      \"data\":{\n        \"event_name\":\"event2\",\n        \"success\":true\n      },\n      \"attributes\":{\n        \"event_name\":\"event2\"\n      },\n      \"delivery_attempts\":0,\n      \"expired_at\":\"2022-10-19T23:51:36.176050\",\n      \"scheduled_at\":\"2022-10-05T23:51:36.176050\",\n      \"created_at\":\"2022-10-05T23:51:36.176050\",\n      \"updated_at\":\"2022-10-05T23:51:36.176050\"\n    }\n  ]\n}\n```\n\n## Dead queue support\n\nThe idea of the dead queue is to move messages that could not be processed to another queue, this can be done using the combination of dead_queue_id and message_max_deliveries fields.\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/queues' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"id\": \"all-events-dead\",\n  \"ack_deadline_seconds\": 30,\n  \"message_retention_seconds\": 1209600\n}'\n\nHTTP/1.1 201 Created\ndate: Thu, 06 Oct 2022 00:33:03 GMT\nserver: uvicorn\ncontent-length: 260\ncontent-type: application/json\n\n{\n  \"id\":\"all-events-dead\",\n  \"topic_id\":null,\n  \"dead_queue_id\":null,\n  \"ack_deadline_seconds\":30,\n  \"message_retention_seconds\":1209600,\n  \"message_filters\":null,\n  \"message_max_deliveries\":null,\n  \"delivery_delay_seconds\":null,\n  \"created_at\":\"2022-10-06T00:33:04.707829\",\n  \"updated_at\":\"2022-10-06T00:33:04.707829\"\n}\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/queues/all-events' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"topic_id\": \"events\",\n  \"ack_deadline_seconds\": 30,\n  \"message_retention_seconds\": 1209600,\n  \"dead_queue_id\": \"all-events-dead\",\n  \"message_max_deliveries\": 2\n}'\n\nHTTP/1.1 200 OK\ndate: Thu, 06 Oct 2022 01:05:55 GMT\nserver: uvicorn\ncontent-length: 269\ncontent-type: application/json\n\n{\n  \"id\":\"all-events\",\n  \"topic_id\":\"events\",\n  \"dead_queue_id\":\"all-events-dead\",\n  \"ack_deadline_seconds\":30,\n  \"message_retention_seconds\":1209600,\n  \"message_filters\":null,\n  \"message_max_deliveries\":2,\n  \"delivery_delay_seconds\":null,\n  \"created_at\":\"2022-10-05T21:51:44.684743\",\n  \"updated_at\":\"2022-10-06T01:05:56.066023\"\n}\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/messages' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Thu, 06 Oct 2022 01:07:50 GMT\nserver: uvicorn\ncontent-length: 700\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"1dd422ad-7d20-4257-94c0-00fc1fbb8092\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"success\":true,\n        \"event_name\":\"event1\"\n      },\n      \"attributes\":{\n        \"event_name\":\"event1\"\n      },\n      \"delivery_attempts\":1,\n      \"expired_at\":\"2022-10-19T23:43:33.265369\",\n      \"scheduled_at\":\"2022-10-06T01:08:21.408095\",\n      \"created_at\":\"2022-10-05T23:43:33.265369\",\n      \"updated_at\":\"2022-10-06T01:07:51.408095\"\n    },\n    {\n      \"id\":\"8856ea21-665f-40a1-b576-33fa067c6a7a\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"success\":true,\n        \"event_name\":\"event2\"\n      },\n      \"attributes\":{\n        \"event_name\":\"event2\"\n      },\n      \"delivery_attempts\":1,\n      \"expired_at\":\"2022-10-19T23:51:36.175915\",\n      \"scheduled_at\":\"2022-10-06T01:08:21.408095\",\n      \"created_at\":\"2022-10-05T23:51:36.175915\",\n      \"updated_at\":\"2022-10-06T01:07:51.408095\"\n    }\n  ]\n}\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/messages/1dd422ad-7d20-4257-94c0-00fc1fbb8092/nack' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 204 No Content\ndate: Thu, 06 Oct 2022 01:09:54 GMT\nserver: uvicorn\ncontent-type: application/json\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/messages/8856ea21-665f-40a1-b576-33fa067c6a7a/nack' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 204 No Content\ndate: Thu, 06 Oct 2022 01:10:26 GMT\nserver: uvicorn\ncontent-type: application/json\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/messages' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Thu, 06 Oct 2022 01:10:49 GMT\nserver: uvicorn\ncontent-length: 700\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"1dd422ad-7d20-4257-94c0-00fc1fbb8092\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"success\":true,\n        \"event_name\":\"event1\"\n      },\n      \"attributes\":{\n        \"event_name\":\"event1\"\n      },\n      \"delivery_attempts\":2,\n      \"expired_at\":\"2022-10-19T23:43:33.265369\",\n      \"scheduled_at\":\"2022-10-06T01:11:19.631164\",\n      \"created_at\":\"2022-10-05T23:43:33.265369\",\n      \"updated_at\":\"2022-10-06T01:10:49.631164\"\n    },\n    {\n      \"id\":\"8856ea21-665f-40a1-b576-33fa067c6a7a\",\n      \"queue_id\":\"all-events\",\n      \"data\":{\n        \"success\":true,\n        \"event_name\":\"event2\"\n      },\n      \"attributes\":{\n        \"event_name\":\"event2\"\n      },\n      \"delivery_attempts\":2,\n      \"expired_at\":\"2022-10-19T23:51:36.175915\",\n      \"scheduled_at\":\"2022-10-06T01:11:19.631164\",\n      \"created_at\":\"2022-10-05T23:51:36.175915\",\n      \"updated_at\":\"2022-10-06T01:10:49.631164\"\n    }\n  ]\n}\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/messages/1dd422ad-7d20-4257-94c0-00fc1fbb8092/nack' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 204 No Content\ndate: Thu, 06 Oct 2022 01:11:34 GMT\nserver: uvicorn\ncontent-type: application/json\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/messages/8856ea21-665f-40a1-b576-33fa067c6a7a/nack' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 204 No Content\ndate: Thu, 06 Oct 2022 01:12:03 GMT\nserver: uvicorn\ncontent-type: application/json\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/stats' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Thu, 06 Oct 2022 01:13:14 GMT\nserver: uvicorn\ncontent-length: 69\ncontent-type: application/json\n\n{\"num_undelivered_messages\":0,\"oldest_unacked_message_age_seconds\":0}\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events-dead/stats' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Thu, 06 Oct 2022 01:13:43 GMT\nserver: uvicorn\ncontent-length: 72\ncontent-type: application/json\n\n{\"num_undelivered_messages\":2,\"oldest_unacked_message_age_seconds\":5410}\n```\n\n## Redrive support\n\nWith redrive you can move messages between queues, we usually use this feature to move messages from the dead queue to the original queue.\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/stats' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Fri, 07 Oct 2022 20:13:15 GMT\nserver: uvicorn\ncontent-length: 69\ncontent-type: application/json\n\n{\"num_undelivered_messages\":0,\"oldest_unacked_message_age_seconds\":0}\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events-dead/stats' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Fri, 07 Oct 2022 20:13:36 GMT\nserver: uvicorn\ncontent-length: 71\ncontent-type: application/json\n\n{\"num_undelivered_messages\":2,\"oldest_unacked_message_age_seconds\":573}\n```\n\n```bash\ncurl -i -X 'PUT' \\\n  'http://localhost:8000/queues/all-events-dead/redrive' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"destination_queue_id\": \"all-events\"\n}'\n\nHTTP/1.1 204 No Content\ndate: Fri, 07 Oct 2022 20:16:39 GMT\nserver: uvicorn\ncontent-type: application/json\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/all-events/stats' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Fri, 07 Oct 2022 20:17:09 GMT\nserver: uvicorn\ncontent-length: 71\ncontent-type: application/json\n\n{\"num_undelivered_messages\":2,\"oldest_unacked_message_age_seconds\":787}\n```\n\n## Delay queues\n\nDelay queues let you postpone the delivery of new messages to consumers for a number of seconds.\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/queues' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"id\": \"delayed-events\",\n  \"topic_id\": \"events\",\n  \"ack_deadline_seconds\": 30,\n  \"message_retention_seconds\": 1209600,\n  \"delivery_delay_seconds\": 30\n}'\n\nHTTP/1.1 201 Created\ndate: Sat, 19 Nov 2022 17:53:42 GMT\nserver: uvicorn\ncontent-length: 291\ncontent-type: application/json\n\n{\n  \"id\":\"delayed-events\",\n  \"topic_id\":\"events\",\n  \"dead_queue_id\":null,\n  \"ack_deadline_seconds\":30,\n  \"message_retention_seconds\":1209600,\n  \"message_filters\":null,\n  \"message_max_deliveries\":null,\n  \"delivery_delay_seconds\":30,\n  \"created_at\":\"2022-11-19T17:53:42.858140\",\n  \"updated_at\":\"2022-11-19T17:53:42.858140\"\n}\n```\n\n```bash\ncurl -i -X 'POST' \\\n  'http://localhost:8000/topics/events/messages' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"data\": {\"event_name\": \"event3\", \"success\": true},\n  \"attributes\": {\"event_name\": \"event3\"}\n}'\n\nHTTP/1.1 201 Created\ndate: Sat, 19 Nov 2022 18:02:08 GMT\nserver: uvicorn\ncontent-length: 359\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"ed42463c-7725-4c3d-9de0-142bb0074be6\",\n      \"queue_id\":\"delayed-events\",\n      \"data\":{\n        \"event_name\":\"event3\",\n        \"success\":true\n      },\n      \"attributes\":{\n        \"event_name\":\"event3\"\n      },\n      \"delivery_attempts\":0,\n      \"expired_at\":\"2022-12-03T18:02:09.435449\",\n      \"scheduled_at\":\"2022-11-19T18:02:39.435449\",\n      \"created_at\":\"2022-11-19T18:02:09.435449\",\n      \"updated_at\":\"2022-11-19T18:02:09.435449\"\n    }\n  ]\n}\n```\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/delayed-events/messages' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Sat, 19 Nov 2022 18:02:24 GMT\nserver: uvicorn\ncontent-length: 11\ncontent-type: application/json\n\n{\"data\":[]}\n```\n\nWait for 30 seconds and try again:\n\n```bash\ncurl -i -X 'GET' \\\n  'http://localhost:8000/queues/delayed-events/messages' \\\n  -H 'accept: application/json'\n\nHTTP/1.1 200 OK\ndate: Sat, 19 Nov 2022 18:02:58 GMT\nserver: uvicorn\ncontent-length: 359\ncontent-type: application/json\n\n{\n  \"data\":[\n    {\n      \"id\":\"ed42463c-7725-4c3d-9de0-142bb0074be6\",\n      \"queue_id\":\"delayed-events\",\n      \"data\":{\n        \"success\":true,\n        \"event_name\":\"event3\"\n      },\n      \"attributes\":{\n        \"event_name\":\"event3\"\n      },\n      \"delivery_attempts\":1,\n      \"expired_at\":\"2022-12-03T18:02:09.435449\",\n      \"scheduled_at\":\"2022-11-19T18:03:28.853622\",\n      \"created_at\":\"2022-11-19T18:02:09.435449\",\n      \"updated_at\":\"2022-11-19T18:02:58.853622\"\n    }\n  ]\n}\n```\n\n## Prometheus metrics\n\nYou can enable prometheus metrics using the environment variable `fastqueue_enable_prometheus_metrics='true'`.\n\n```bash\ndocker run --name fastqueue-server \\\n    --restart unless-stopped \\\n    -e fastqueue_database_url='postgresql+psycopg2://fastqueue:fastqueue@localhost:5432/fastqueue' \\\n    -e fastqueue_server_port=8000 \\\n    -e fastqueue_server_num_workers=1 \\\n    -e fastqueue_enable_prometheus_metrics='true' \\\n    --network=\"host\" \\\n    quay.io/allisson/fastqueue server\n```\n\n```bash\ncurl -i -X 'GET' 'http://localhost:8000/metrics'\n\nHTTP/1.1 200 OK\ndate: Fri, 14 Oct 2022 15:58:56 GMT\nserver: uvicorn\ncontent-length: 4432\ncontent-type: text/plain; version=0.0.4; charset=utf-8\n\n# HELP python_gc_objects_collected_total Objects collected during gc\n# TYPE python_gc_objects_collected_total counter\npython_gc_objects_collected_total{generation=\"0\"} 427.0\npython_gc_objects_collected_total{generation=\"1\"} 198.0\npython_gc_objects_collected_total{generation=\"2\"} 16.0\n# HELP python_gc_objects_uncollectable_total Uncollectable object found during GC\n# TYPE python_gc_objects_uncollectable_total counter\npython_gc_objects_uncollectable_total{generation=\"0\"} 0.0\npython_gc_objects_uncollectable_total{generation=\"1\"} 0.0\npython_gc_objects_uncollectable_total{generation=\"2\"} 0.0\n# HELP python_gc_collections_total Number of times this generation was collected\n# TYPE python_gc_collections_total counter\npython_gc_collections_total{generation=\"0\"} 241.0\npython_gc_collections_total{generation=\"1\"} 21.0\npython_gc_collections_total{generation=\"2\"} 1.0\n# HELP python_info Python platform information\n# TYPE python_info gauge\npython_info{implementation=\"CPython\",major=\"3\",minor=\"10\",patchlevel=\"7\",version=\"3.10.7\"} 1.0\n# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n# TYPE process_virtual_memory_bytes gauge\nprocess_virtual_memory_bytes 2.11103744e+08\n# HELP process_resident_memory_bytes Resident memory size in bytes.\n# TYPE process_resident_memory_bytes gauge\nprocess_resident_memory_bytes 7.9659008e+07\n# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n# TYPE process_start_time_seconds gauge\nprocess_start_time_seconds 1.66576313315e+09\n# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.\n# TYPE process_cpu_seconds_total counter\nprocess_cpu_seconds_total 0.48\n# HELP process_open_fds Number of open file descriptors.\n# TYPE process_open_fds gauge\nprocess_open_fds 23.0\n# HELP process_max_fds Maximum number of open file descriptors.\n# TYPE process_max_fds gauge\nprocess_max_fds 1024.0\n# HELP http_requests_total Total number of requests by method, status and handler.\n# TYPE http_requests_total counter\n# HELP http_request_size_bytes Content length of incoming requests by handler. Only value of header is respected. Otherwise ignored. No percentile calculated.\n# TYPE http_request_size_bytes summary\n# HELP http_response_size_bytes Content length of outgoing responses by handler. Only value of header is respected. Otherwise ignored. No percentile calculated.\n# TYPE http_response_size_bytes summary\n# HELP http_request_duration_highr_seconds Latency with many buckets but no API specific labels. Made for more accurate percentile calculations.\n# TYPE http_request_duration_highr_seconds histogram\nhttp_request_duration_highr_seconds_bucket{le=\"0.01\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"0.025\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"0.05\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"0.075\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"0.1\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"0.25\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"0.5\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"0.75\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"1.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"1.5\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"2.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"2.5\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"3.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"3.5\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"4.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"4.5\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"5.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"7.5\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"10.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"30.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"60.0\"} 0.0\nhttp_request_duration_highr_seconds_bucket{le=\"+Inf\"} 0.0\nhttp_request_duration_highr_seconds_count 0.0\nhttp_request_duration_highr_seconds_sum 0.0\n# HELP http_request_duration_highr_seconds_created Latency with many buckets but no API specific labels. Made for more accurate percentile calculations.\n# TYPE http_request_duration_highr_seconds_created gauge\nhttp_request_duration_highr_seconds_created 1.6657631341236415e+09\n# HELP http_request_duration_seconds Latency with only few buckets by handler. Made to be only used if aggregation by handler is important.\n# TYPE http_request_duration_seconds histogram\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallisson%2Ffastqueue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallisson%2Ffastqueue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallisson%2Ffastqueue/lists"}