{"id":20560443,"url":"https://github.com/vodolaz095/dqueue","last_synced_at":"2025-08-22T13:09:31.698Z","repository":{"id":211553486,"uuid":"729442557","full_name":"vodolaz095/dqueue","owner":"vodolaz095","description":"Golang deffered queue","archived":false,"fork":false,"pushed_at":"2024-08-06T09:37:04.000Z","size":14,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-16T19:06:07.271Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/vodolaz095.png","metadata":{"files":{"readme":"README.md","changelog":null,"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},"funding":{"custom":["https://www.tinkoff.ru/rm/ostroumov.anatoliy2/4HFzm76801/"]}},"created_at":"2023-12-09T08:39:11.000Z","updated_at":"2024-08-06T09:37:08.000Z","dependencies_parsed_at":"2023-12-09T10:26:25.699Z","dependency_job_id":"9a733d96-3f48-4cbd-b5fd-9e49b1407e9f","html_url":"https://github.com/vodolaz095/dqueue","commit_stats":null,"previous_names":["vodolaz095/dqueue"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodolaz095%2Fdqueue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodolaz095%2Fdqueue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodolaz095%2Fdqueue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodolaz095%2Fdqueue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vodolaz095","download_url":"https://codeload.github.com/vodolaz095/dqueue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242168798,"owners_count":20083167,"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-11-16T03:54:33.474Z","updated_at":"2025-08-22T13:09:31.679Z","avatar_url":"https://github.com/vodolaz095.png","language":"Go","funding_links":["https://www.tinkoff.ru/rm/ostroumov.anatoliy2/4HFzm76801/"],"categories":["Data Structures and Algorithms","数据结构与算法","Data Integration Frameworks"],"sub_categories":["Queues","队列"],"readme":"D(EFERRED) Queue\n======================\n\n[![Go](https://github.com/vodolaz095/dqueue/actions/workflows/go.yml/badge.svg)](https://github.com/vodolaz095/dqueue/actions/workflows/go.yml)\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/vodolaz095/dqueue)](https://pkg.go.dev/github.com/vodolaz095/dqueue?tab=doc)\n[![Go Report Card](https://goreportcard.com/badge/github.com/vodolaz095/dqueue)](https://goreportcard.com/report/github.com/vodolaz095/dqueue)\n\n\nIt was a test task i finished in 2 hours in 2017 year, i polished code a little, created\nexample with contexts and added 100% unit tests coverage in 2023.\n\nWhat does it do?\n======================\nWith this package we can make deferred queue of tasks to be executed, like\n`execute this in 3 minutes`, `execute that in 15 seconds from now` and so on.\nThen, we can consume this tasks by concurrent goroutines and they (tasks) will be\nprovided to consumers in proper order, like first task will be `that` to be executed in\n15 seconds from now.\n\nIt is worth notice, that any element of queue can be of different type, and typecasting can be slow.\nIf you need something less agile and more performant, you can see generic based alternative - https://github.com/vodolaz095/dgqueue\n\nBasic usage\n=====================\n\nMake queue handler:\n```go\nhandler := dqueue.New() // import \"github.com/vodolaz095/dqueue\"\n\n// payload can be anything - number, string, buffer, struct...\nsomething := \"task\"\n\n// Create tasks to be executed in future\nhandler.ExecuteAt(something, time.Now().Add(time.Minute))\nhandler.ExecuteAfter(something, time.Minute)\n\n// Extract task ready to be executed\ntask, ready := handler.Get()\nif ready { // task is ready\n    fmt.Printf(\"Task %s is ready to be executed at %s\",\n\t\ttask.Payload.(string), \n\t\ttask.ExecuteAt.Format(time.Kitchen),\n\t)\n} else {\n\tfmt.Println(\"No tasks are ready to be executed\")\n}\n// Count tasks left\ntasksInQueue := handler.Len()\n\n// Extract all tasks, so, we can, for example, save all delivery queue  before closing application\ntasks:= handler.Dump()\n\n// Prune queue:\nhandler.Prune()\n```\n\nConcurrent consumers example\n======================\nSee full example at [example.go](example%2Fexample.go)\n\n```go\n\nhandler := dqueue.New() // import \"github.com/vodolaz095/dqueue\"\n\n// Publish tasks\nsomething := \"task\" // payload can be anything - number, string, buffer, struct...\nhandler.ExecuteAt(something, time.Now().Add(time.Minute))\nhandler.ExecuteAfter(something, time.Minute)\n\n// make global context to be canceled when application is stopping\nwg := sync.WaitGroup{}\nmainCtx, mainCancel := context.WithTimeout(context.Background(), 3*time.Second)\ndefer mainCancel()\n\n// Start concurrent consumers\nwg := sync.WaitGroup{}\nfor j := 0; j \u003c 10; j++ {\n    wg.Add(1)\n    go func(workerNumber int, initialCtx context.Context) {\n        ctx, cancel := context.WithCancel(initialCtx)\n        defer cancel()\n        ticker := time.NewTicker(time.Millisecond)\n        for {\n            select {\n            case t := \u003c-ticker.C:\n                task, ready := handler.Get()\n                if ready { // task is ready\n                    err := ProcessTask(task)\n                    if err != nil { // aka, requeue message to be delivered in 1 minute\n                      handler.ExecuteAfter(something, time.Minute)\n                    }\n                }\n                break\n            case \u003c-ctx.Done():\n                fmt.Printf(\"Closing worker %v, there are %v tasks in queue\\n\", workerNumber, handler.Len())\n                wg.Done()\n                ticker.Stop()\n                return\n            }\n        }\n    }(j, mainCtx)\n}\nwg.Wait()\n\n// See tasks left, so they can be restored somehow when application is restarted\ntasks := handler.Dump()\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvodolaz095%2Fdqueue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvodolaz095%2Fdqueue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvodolaz095%2Fdqueue/lists"}