Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vodolaz095/dqueue
Golang deffered queue
https://github.com/vodolaz095/dqueue
Last synced: about 4 hours ago
JSON representation
Golang deffered queue
- Host: GitHub
- URL: https://github.com/vodolaz095/dqueue
- Owner: vodolaz095
- License: mit
- Created: 2023-12-09T08:39:11.000Z (11 months ago)
- Default Branch: master
- Last Pushed: 2024-08-06T09:37:04.000Z (3 months ago)
- Last Synced: 2024-08-06T11:22:42.149Z (3 months ago)
- Language: Go
- Size: 13.7 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
D(EFERRED) Queue
======================[![Go](https://github.com/vodolaz095/dqueue/actions/workflows/go.yml/badge.svg)](https://github.com/vodolaz095/dqueue/actions/workflows/go.yml)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/vodolaz095/dqueue)](https://pkg.go.dev/github.com/vodolaz095/dqueue?tab=doc)
[![Go Report Card](https://goreportcard.com/badge/github.com/vodolaz095/dqueue)](https://goreportcard.com/report/github.com/vodolaz095/dqueue)It was a test task i finished in 2 hours in 2017 year, i polished code a little, created
example with contexts and added 100% unit tests coverage in 2023.What does it do?
======================
With this package we can make deferred queue of tasks to be executed, like
`execute this in 3 minutes`, `execute that in 15 seconds from now` and so on.
Then, we can consume this tasks by concurrent goroutines and they (tasks) will be
provided to consumers in proper order, like first task will be `that` to be executed in
15 seconds from now.Basic usage
=====================Make queue handler:
```go
handler := dqueue.New() // import "github.com/vodolaz095/dqueue"// payload can be anything - number, string, buffer, struct...
something := "task"// Create tasks to be executed in future
handler.ExecuteAt(something, time.Now().Add(time.Minute))
handler.ExecuteAfter(something, time.Minute)// Extract task ready to be executed
task, ready := handler.Get()
if ready { // task is ready
fmt.Printf("Task %s is ready to be executed at %s",
task.Payload.(string),
task.ExecuteAt.Format(time.Kitchen),
)
} else {
fmt.Println("No tasks are ready to be executed")
}
// Count tasks left
tasksInQueue := handler.Len()// Extract all tasks, so, we can, for example, save all delivery queue before closing application
tasks:= handler.Dump()// Prune queue:
handler.Prune()
```Concurrent consumers example
======================
See full example at [example.go](example%2Fexample.go)```go
handler := dqueue.New() // import "github.com/vodolaz095/dqueue"
// Publish tasks
something := "task" // payload can be anything - number, string, buffer, struct...
handler.ExecuteAt(something, time.Now().Add(time.Minute))
handler.ExecuteAfter(something, time.Minute)// make global context to be canceled when application is stopping
wg := sync.WaitGroup{}
mainCtx, mainCancel := context.WithTimeout(context.Background(), 3*time.Second)
defer mainCancel()// Start concurrent consumers
wg := sync.WaitGroup{}
for j := 0; j < 10; j++ {
wg.Add(1)
go func(workerNumber int, initialCtx context.Context) {
ctx, cancel := context.WithCancel(initialCtx)
defer cancel()
ticker := time.NewTicker(time.Millisecond)
for {
select {
case t := <-ticker.C:
task, ready := handler.Get()
if ready { // task is ready
err := ProcessTask(task)
if err != nil { // aka, requeue message to be delivered in 1 minute
handler.ExecuteAfter(something, time.Minute)
}
}
break
case <-ctx.Done():
fmt.Printf("Closing worker %v, there are %v tasks in queue\n", workerNumber, handler.Len())
wg.Done()
ticker.Stop()
return
}
}
}(j, mainCtx)
}
wg.Wait()// See tasks left, so they can be restored somehow when application is restarted
tasks := handler.Dump()```