{"id":13560828,"url":"https://github.com/vgarvardt/gue","last_synced_at":"2025-05-15T14:07:38.752Z","repository":{"id":37746866,"uuid":"271863305","full_name":"vgarvardt/gue","owner":"vgarvardt","description":"Golang queue on top of PostgreSQL","archived":false,"fork":false,"pushed_at":"2025-05-06T18:54:45.000Z","size":885,"stargazers_count":287,"open_issues_count":12,"forks_count":28,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-13T19:08:15.474Z","etag":null,"topics":["go","golang","postgres","postgresql","queue"],"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/vgarvardt.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":["paypal.me/vgarvardt"]}},"created_at":"2020-06-12T18:17:47.000Z","updated_at":"2025-05-06T18:54:48.000Z","dependencies_parsed_at":"2023-12-18T14:32:58.900Z","dependency_job_id":"dde61c14-f31b-4d18-a189-cdcaa1b67604","html_url":"https://github.com/vgarvardt/gue","commit_stats":{"total_commits":362,"total_committers":21,"mean_commits":"17.238095238095237","dds":0.4779005524861878,"last_synced_commit":"48af7e36d80f42e2ff996656a853833b64563392"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgarvardt%2Fgue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgarvardt%2Fgue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgarvardt%2Fgue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgarvardt%2Fgue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vgarvardt","download_url":"https://codeload.github.com/vgarvardt/gue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355335,"owners_count":22057354,"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":["go","golang","postgres","postgresql","queue"],"created_at":"2024-08-01T13:00:49.895Z","updated_at":"2025-05-15T14:07:33.739Z","avatar_url":"https://github.com/vgarvardt.png","language":"Go","funding_links":["paypal.me/vgarvardt"],"categories":["Go"],"sub_categories":[],"readme":"# gue\n\n[![GoDev](https://img.shields.io/static/v1?label=godev\u0026message=reference\u0026color=00add8)](https://pkg.go.dev/github.com/vgarvardt/gue/v5)\n[![Coverage Status](https://codecov.io/gh/vgarvardt/gue/branch/master/graph/badge.svg)](https://codecov.io/gh/vgarvardt/gue)\n[![ReportCard](https://goreportcard.com/badge/github.com/vgarvardt/gue)](https://goreportcard.com/report/github.com/vgarvardt/gue)\n[![License](https://img.shields.io/npm/l/express.svg)](http://opensource.org/licenses/MIT)\n\nGue is Golang queue on top of PostgreSQL that uses transaction-level locks.\n\nOriginally this project used to be a fork of [bgentry/que-go](https://github.com/bgentry/que-go)\nbut because of some backward-compatibility breaking changes and original library author not being very responsive for\nPRs I turned fork into standalone project. Version 2 breaks internal backward-compatibility with the original project -\nDB table and all the internal logic (queries, algorithms) is completely rewritten.\n\nThe name Gue is yet another silly word transformation: Queue -\u003e Que, Go + Que -\u003e Gue.\n\n## Install\n\n```shell\ngo get -u github.com/vgarvardt/gue/v5\n```\n\nAdditionally, you need to apply [DB migration](migrations/schema.sql).\n\n## Usage Example\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/jackc/pgx/v5/pgxpool\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/vgarvardt/gue/v5\"\n\t\"github.com/vgarvardt/gue/v5/adapter/pgxv5\"\n)\n\nconst (\n\tprinterQueue   = \"name_printer\"\n\tjobTypePrinter = \"PrintName\"\n)\n\ntype printNameArgs struct {\n\tName string\n}\n\nfunc main() {\n\tprintName := func(ctx context.Context, j *gue.Job) error {\n\t\tvar args printNameArgs\n\t\tif err := json.Unmarshal(j.Args, \u0026args); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfmt.Printf(\"Hello %s!\\n\", args.Name)\n\t\treturn nil\n\t}\n\n\tpgxCfg, err := pgxpool.ParseConfig(os.Getenv(\"DATABASE_URL\"))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tpgxPool, err := pgxpool.NewWithConfig(context.Background(), pgxCfg)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer pgxPool.Close()\n\n\tpoolAdapter := pgxv5.NewConnPool(pgxPool)\n\n\tgc, err := gue.NewClient(poolAdapter)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\twm := gue.WorkMap{\n\t\tjobTypePrinter: printName,\n\t}\n\n\tfinishedJobsLog := func(ctx context.Context, j *gue.Job, err error) {\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tj.Tx().Exec(\n\t\t\tctx,\n\t\t\t\"INSERT INTO finished_jobs_log (queue, type, run_at) VALUES ($1, $2, now())\",\n\t\t\tj.Queue,\n\t\t\tj.Type,\n\t\t)\n\t}\n\n\t// create a pool w/ 2 workers\n\tworkers, err := gue.NewWorkerPool(gc, wm, 2, gue.WithPoolQueue(printerQueue), gue.WithPoolHooksJobDone(finishedJobsLog))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tctx, shutdown := context.WithCancel(context.Background())\n\n\t// work jobs in goroutine\n\tg, gctx := errgroup.WithContext(ctx)\n\tg.Go(func() error {\n\t\terr := workers.Run(gctx)\n\t\tif err != nil {\n\t\t\t// In a real-world applications, use a better way to shut down\n\t\t\t// application on unrecoverable error. E.g. fx.Shutdowner from\n\t\t\t// go.uber.org/fx module.\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\treturn err\n\t})\n\n\targs, err := json.Marshal(printNameArgs{Name: \"vgarvardt\"})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tj := \u0026gue.Job{\n\t\tType:  jobTypePrinter,\n\t\tQueue: printerQueue,\n\t\tArgs:  args,\n\t}\n\tif err := gc.Enqueue(context.Background(), j); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tj = \u0026gue.Job{\n\t\tType:  jobTypePrinter,\n\t\tQueue: printerQueue,\n\t\tRunAt: time.Now().UTC().Add(30 * time.Second), // delay 30 seconds\n\t\tArgs:  args,\n\t}\n\tif err := gc.Enqueue(context.Background(), j); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\ttime.Sleep(30 * time.Second) // wait for while\n\n\t// send shutdown signal to worker\n\tshutdown()\n\tif err := g.Wait(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\n```\n\n## PostgreSQL drivers\n\nPackage supports several PostgreSQL drivers using adapter interface internally. Currently, adapters for the following\ndrivers have been implemented:\n\n- [github.com/jackc/pgx/v5](https://github.com/jackc/pgx)\n- [github.com/jackc/pgx/v4](https://github.com/jackc/pgx)\n- [github.com/lib/pq](https://github.com/lib/pq)\n\n### `pgx/v5`\n\n```go\npackage main\n\nimport (\n  \"log\"\n  \"os\"\n\n  \"github.com/jackc/pgx/v5/pgxpool\"\n\n  \"github.com/vgarvardt/gue/v5\"\n  \"github.com/vgarvardt/gue/v5/adapter/pgxv5\"\n)\n\nfunc main() {\n  pgxCfg, err := pgxpool.ParseConfig(os.Getenv(\"DATABASE_URL\"))\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  pgxPool, err := pgxpool.NewConfig(context.Background(), pgxCfg)\n  if err != nil {\n    log.Fatal(err)\n  }\n  defer pgxPool.Close()\n\n  poolAdapter := pgxv5.NewConnPool(pgxPool)\n\n  gc, err := gue.NewClient(poolAdapter)\n  ...\n}\n```\n\n### `pgx/v4`\n\n```go\npackage main\n\nimport (\n  \"context\"\n  \"log\"\n  \"os\"\n\n  \"github.com/jackc/pgx/v4/pgxpool\"\n\n  \"github.com/vgarvardt/gue/v5\"\n  \"github.com/vgarvardt/gue/v5/adapter/pgxv4\"\n)\n\nfunc main() {\n  pgxCfg, err := pgxpool.ParseConfig(os.Getenv(\"DATABASE_URL\"))\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  pgxPool, err := pgxpool.ConnectConfig(context.Background(), pgxCfg)\n  if err != nil {\n    log.Fatal(err)\n  }\n  defer pgxPool.Close()\n\n  poolAdapter := pgxv4.NewConnPool(pgxPool)\n\n  gc, err := gue.NewClient(poolAdapter)\n  ...\n}\n```\n\n### `lib/pq`\n\n```go\npackage main\n\nimport (\n  \"database/sql\"\n  \"log\"\n  \"os\"\n\n  _ \"github.com/lib/pq\" // register postgres driver\n\n  \"github.com/vgarvardt/gue/v5\"\n  \"github.com/vgarvardt/gue/v5/adapter/libpq\"\n)\n\nfunc main() {\n  db, err := sql.Open(\"postgres\", os.Getenv(\"DATABASE_URL\"))\n  if err != nil {\n    log.Fatal(err)\n  }\n  defer db.Close()\n\n  poolAdapter := libpq.NewConnPool(db)\n\n  gc, err := gue.NewClient(poolAdapter)\n  ...\n}\n```\n\n## Logging\n\nPackage supports several logging libraries using adapter interface internally. Currently, adapters for the following\ndrivers have been implemented:\n\n- NoOp (`adapter.NoOpLogger`) - default adapter that does nothing, so it is basically `/dev/null` logger\n- Stdlib `log` - adapter that uses [`log`](https://golang.org/pkg/log/) logger for logs output. Instantiate it\n  with `adapter.NewStdLogger(...)`.\n- Uber `zap` - adapter that uses [`go.uber.org/zap`](https://pkg.go.dev/go.uber.org/zap) logger for logs output.\n  Instantiate it with `adapter/zap.New(...)`.\n- Olivier Poitrey's `zerolog` - adapter that uses [`github.com/rs/zerolog`](https://pkg.go.dev/github.com/rs/zerolog)\n  logger for logs output. Instantiate it with `adapter/zerolog.New(...)`.\n- Stdlib `slog` - adapter that uses [`log/slog`](https://pkg.go.dev/log/slog)\n  logger for logs output. Instantiate it with `adapter/slog.New(...)`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgarvardt%2Fgue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvgarvardt%2Fgue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgarvardt%2Fgue/lists"}