{"id":25343699,"url":"https://github.com/jarshwah/dispatchr","last_synced_at":"2026-05-01T06:31:35.033Z","repository":{"id":276585353,"uuid":"504757686","full_name":"jarshwah/dispatchr","owner":"jarshwah","description":"An opinionated background task system","archived":false,"fork":false,"pushed_at":"2025-02-22T04:18:45.000Z","size":31,"stargazers_count":0,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-04T12:44:15.350Z","etag":null,"topics":["golang","python","taskscheduler"],"latest_commit_sha":null,"homepage":"","language":"Go","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/jarshwah.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-18T05:56:03.000Z","updated_at":"2025-02-22T04:18:49.000Z","dependencies_parsed_at":"2025-02-09T08:23:57.218Z","dependency_job_id":"2cf545ea-c16f-4496-8473-807e68faf845","html_url":"https://github.com/jarshwah/dispatchr","commit_stats":null,"previous_names":["jarshwah/dispatchr"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jarshwah/dispatchr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarshwah%2Fdispatchr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarshwah%2Fdispatchr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarshwah%2Fdispatchr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarshwah%2Fdispatchr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jarshwah","download_url":"https://codeload.github.com/jarshwah/dispatchr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarshwah%2Fdispatchr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32487300,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["golang","python","taskscheduler"],"created_at":"2025-02-14T10:57:42.294Z","updated_at":"2026-05-01T06:31:35.018Z","avatar_url":"https://github.com/jarshwah.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dispatchr\n\nA background task service built on [River Queue](https://riverqueue.com/).\n\nThis software is under development, is proof-of-concept *only*, and has not yet been productionised (or, indeed, fully implemented).\n\n## What is this?\n\nA database-backed background task service.\n\nClients submit tasks over HTTP to dispatchr-recorder, which stores the task in a database, and signals success to the client - letting it know the task has been successfully confirmed.\n\nA separate process, dispatchr-worker, reads tasks from the database, executes them, and records the results.\n\nA task is a JSON object with the following fields:\n\n```json\n{\n  \"target\": \"https://client.domain/endpoint\",\n  \"taskName\": \"client-task-name\",\n  \"taskArgs\": {\"client\": \"args\", \"go\": \"here\", \"nested\": {\"data\": \"too\"}},\n}\n```\n\nThe dispatchr worker will pick up this task, POST `taskName` and `taskArgs` to `urlTarget`, and record the result.\n\nIf the client responds with a 2xx status code, the task is marked as successful. If the client responds with a 4xx or 5xx status code, the task is marked as failed.\n\n## Why would I use this?\n\nSimply, because most background task systems suck. They:\n\n- are tightly coupled to the language or framework of the main application\n- do not come with good defaults\n- are typically backed by a message queue, which does not allow an operator to inspect the *state* of the system\n- prioritise throughput over correctness\n- are difficult to orchestrate\n\nThe core design principles of dispatchr is that HTTP is useful to a background task service because:\n\n- Your application is already built to handle HTTP requests\n- You do not need to operate a separate instance of your application that pulls work\n- Your existing HTTP middleware can be used to observe background work and apply rate limits\n- Retry logic can be handled simply with HTTP status codes\n\nYour application submits tasks over HTTP to dispatchr. Publish confirms are enabled *by default*, as choosing to ignore the HTTP response is atypical.\n\nTasks are executed over HTTP by your application. Dispatchr takes care of the scheduling, prioritisation, backpressure, and retries.\nHave a separate lambda service you want to execute asynchronously? Submit a task to dispatchr with a URL target of your lambda service.\n\nSince dispatchr stores tasks in a database, you have full operational visibility into the state of the system. See which tasks are queued, the rate of task execution and submission, failed tasks and their payload, etc. Anyone that has ever tried to debug a failed task in traditional message queue based systems\n\n## Why wouldn't I use this?\n\nSince HTTP and Postgres are baked into the design of dispatchr, you should not use dispatchr if:\n\n- You have long-running tasks (somewhere \u003e 1 minute) due to timeouts\n- You anticipate a volume of tasks that would overwhelm a single Postgres database. TODO: benchmarking to provide specific numbers/guidance.\n- You want strict [transactional enqueuing](https://riverqueue.com/docs/transactional-enqueueing). While River supports transactional enqueueing, dispatchr by design does not as it's deployed as a separate service.\n\n\n# Running dispatchr\n\nBuild the binaries:\n\n```sh\nmake build\n```\n\nCreate a database for dispatchr to use, and export the `DATABASE_URL` environment variable:\n\n```sh\ncreatedb dispatchr\nexport DATABASE_URL=postgres://localhost/dispatchr\n\nriver migrate-up --database-url \"$DATABASE_URL\"\n```\n\nStart the recorder service, which listens for incoming tasks:\n\n```sh\nDATABASE_URL=... go run ./cmd/recorder\n```\n\nStart the worker service, which will dispatch tasks to your application:\n\n```sh\nDATABASE_URL=... go run ./cmd/worker\n```\n\n(Optional): Start up [River UI](https://github.com/riverqueue/riverui) to inspect the state of the system:\n\n```sh\ncurl -L https://github.com/riverqueue/riverui/releases/latest/download/riverui_darwin_arm64.gz | gzip -d \u003e riverui\nchmod +x riverui\nDATABASE_URL=... ./riverui\n```\n\nSubmit your tasks!\n\n```\ncurl --request POST \\\n  --url http://localhost:9090/task \\\n  --data '{\n  \"target\": \"https://client.domain/endpoint\",\n  \"taskName\": \"client-task-name\",\n  \"taskArgs\": {\n    \"data\": \"here\"\n  }\n}'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjarshwah%2Fdispatchr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjarshwah%2Fdispatchr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjarshwah%2Fdispatchr/lists"}