{"id":28578303,"url":"https://github.com/digitalocean/go-workers2","last_synced_at":"2025-07-06T21:38:27.804Z","repository":{"id":34403662,"uuid":"153502633","full_name":"digitalocean/go-workers2","owner":"digitalocean","description":"better-go-workers","archived":false,"fork":false,"pushed_at":"2024-11-01T17:27:25.000Z","size":4648,"stargazers_count":135,"open_issues_count":7,"forks_count":36,"subscribers_count":120,"default_branch":"master","last_synced_at":"2025-01-15T00:19:53.187Z","etag":null,"topics":[],"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/digitalocean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2018-10-17T18:11:41.000Z","updated_at":"2025-01-12T21:29:50.000Z","dependencies_parsed_at":"2024-06-18T16:46:50.825Z","dependency_job_id":"ac778a13-7162-47f7-b251-3225f442e491","html_url":"https://github.com/digitalocean/go-workers2","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-workers2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-workers2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-workers2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-workers2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalocean","download_url":"https://codeload.github.com/digitalocean/go-workers2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-workers2/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259178542,"owners_count":22817388,"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":"2025-06-11T01:09:30.481Z","updated_at":"2025-06-11T01:09:31.299Z","avatar_url":"https://github.com/digitalocean.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/digitalocean/go-workers2.png)](https://travis-ci.org/digitalocean/go-workers2)\n[![GoDoc](https://godoc.org/github.com/digitalocean/go-workers2?status.png)](https://godoc.org/github.com/digitalocean/go-workers2)\n\n[Sidekiq](http://sidekiq.org/) compatible\nbackground workers in [golang](http://golang.org/).\n\n- reliable queueing for all queues using [brpoplpush](http://redis.io/commands/brpoplpush)\n- handles retries\n- support custom middleware\n- customize concurrency per queue\n- responds to Unix signals to safely wait for jobs to finish before exiting.\n- provides stats on what jobs are currently running\n- redis sentinel support\n- well tested\n\nExample usage:\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  workers \"github.com/digitalocean/go-workers2\"\n)\n\nfunc myJob(message *workers.Msg) error {\n  // do something with your message\n  // message.Jid()\n  // message.Args() is a wrapper around go-simplejson (http://godoc.org/github.com/bitly/go-simplejson)\n  return nil\n}\n\nfunc myMiddleware(queue string, mgr *workers.Manager, next workers.JobFunc) workers.JobFunc {\n  return func(message *workers.Msg) (err error) {\n    // do something before each message is processed\n    err = next(message)\n    // do something after each message is processed\n    return\n  }\n}\n\nfunc main() {\n  // Create a manager, which manages workers\n  manager, err := workers.NewManager(workers.Options{\n    // location of redis instance\n    ServerAddr: \"localhost:6379\",\n    // instance of the database\n    Database:   0,\n    // number of connections to keep open with redis\n    PoolSize:   30,\n    // unique process id for this instance of workers (for proper recovery of inprogress jobs on crash)\n    ProcessID:  \"1\",\n  })\n\n  if err != nil {\n    fmt.Println(err)\n  }\n\n  // create a middleware chain with the default middlewares, and append myMiddleware\n  mids := workers.DefaultMiddlewares().Append(myMiddleware)\n\n  // pull messages from \"myqueue\" with concurrency of 10\n  // this worker will not run myMiddleware, but will run the default middlewares\n  manager.AddWorker(\"myqueue\", 10, myJob)\n\n  // pull messages from \"myqueue2\" with concurrency of 20\n  // this worker will run the default middlewares and myMiddleware\n  manager.AddWorker(\"myqueue2\", 20, myJob, mids...)\n\n  // pull messages from \"myqueue3\" with concurrency of 20\n  // this worker will only run myMiddleware\n  manager.AddWorker(\"myqueue3\", 20, myJob, myMiddleware)\n\n  // If you already have a manager and want to enqueue\n  // to the same place:\n  producer := manager.Producer()\n\n  // Alternatively, if you want to create a producer to enqueue messages\n  // producer, err := workers.NewProducer(Options{\n  //   // location of redis instance\n  //   ServerAddr: \"localhost:6379\",\n  //   // instance of the database\n  //   Database:   0,\n  //   // number of connections to keep open with redis\n  //   PoolSize:   30,\n  //   // unique process id for this instance of workers (for proper recovery of inprogress jobs on crash)\n  //   ProcessID:  \"1\",\n  // })\n\n  // Add a job to a queue\n  producer.Enqueue(\"myqueue3\", \"Add\", []int{1, 2})\n\n  // Add a job to a queue with retry\n  producer.EnqueueWithOptions(\"myqueue3\", \"Add\", []int{1, 2}, workers.EnqueueOptions{Retry: true})\n\n  // Add a job to a queue passing the context to redis\n  producer.EnqueueWithContext(ctx.Background(), \"myqueue3\", \"Add\", []int{1, 2}, workers.EnqueueOptions{Retry: true})\n\n  // stats will be available at http://localhost:8080/stats\n  go workers.StartAPIServer(8080)\n\n  // Blocks until process is told to exit via unix signal\n  manager.Run()\n}\n```\n\nWhen running the above code example, it will produce the following output at `localhost:8080/stats`:\n\n```json\n[\n  {\n    \"manager_name\": \"\",\n    \"processed\": 5,\n    \"failed\": 57,\n    \"jobs\": {\n      \"myqueue\": null,\n      \"myqueue2\": null,\n      \"myqueue3\": null\n    },\n    \"enqueued\": {\n      \"myqueue\": 0,\n      \"myqueue2\": 0,\n      \"myqueue3\": 0\n    },\n    \"retry_count\": 4\n  }\n]\n```\n\nDevelopment sponsored by DigitalOcean. Code forked from [github/jrallison/go-workers](https://github.com/jrallison/go-workers). Initial development sponsored by [Customer.io](http://customer.io).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fgo-workers2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalocean%2Fgo-workers2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fgo-workers2/lists"}