Documentation
¶
Overview ¶
Package dque is a fast, embedded, type-safe durable queue for Go. DQue[T any] provides a generic FIFO queue backed by disk segments, eliminating the need for manual type assertions on Dequeue/Peek return values.
Index ¶
- Variables
- type DQue
- func (q *DQue[T]) Close() error
- func (q *DQue[T]) Dequeue() (*T, error)
- func (q *DQue[T]) DequeueBlock() (*T, error)
- func (q *DQue[T]) DiskBytes() int64
- func (q *DQue[T]) Enqueue(obj *T) error
- func (q *DQue[T]) Peek() (*T, error)
- func (q *DQue[T]) PeekBlock() (*T, error)
- func (q *DQue[T]) SegmentNumbers() (int, int)
- func (q *DQue[T]) Size() int
- func (q *DQue[T]) SizeUnsafe() int
- func (q *DQue[T]) Turbo() bool
- func (q *DQue[T]) TurboOff() error
- func (q *DQue[T]) TurboOn() error
- func (q *DQue[T]) TurboSync() error
- type ErrCorruptedSegment
- type ErrUnableToDecode
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrEmpty is returned when attempting to dequeue from an empty queue. ErrEmpty = errors.New("dque is empty") )
var ErrQueueClosed = errors.New("queue is closed")
ErrQueueClosed is the error returned when a queue is closed.
Functions ¶
This section is empty.
Types ¶
type DQue ¶
DQue is the in-memory representation of a type-safe queue on disk. You must never have two *active* DQue instances pointing at the same path on disk. It is acceptable to reconstitute a new instance from disk, but make sure the old instance is never enqueued to (or dequeued from) again.
Example ¶
ExampleDQue shows how the queue works
package main
//
// Example usage
// Run with: go test -v example_test.go
//
import (
"errors"
"fmt"
"log"
"os"
"github.com/lbe/sfpg-go/internal/dque"
)
// Item is what we'll be storing in the queue. It can be any struct
// as long as the fields you want stored are public.
type Item struct {
Name string
Id int
}
// ExampleDQue shows how the queue works
func main() {
qName := "item-queue"
qDir := os.TempDir()
segmentSize := 50
// Create a new queue with segment size of 50
q, err := dque.NewOrOpen[Item](qName, qDir, segmentSize)
if err != nil {
log.Fatal("Error creating new dque ", err)
}
// Add an item to the queue
if err = q.Enqueue(&Item{"Joe", 1}); err != nil {
log.Fatal("Error enqueueing item ", err)
}
log.Println("Size should be 1:", q.Size())
// Properly close a queue
if err = q.Close(); err != nil {
log.Fatal("Error closing dque ", err)
}
// You can reconsitute the queue from disk at any time
q, err = dque.Open[Item](qName, qDir, segmentSize)
if err != nil {
log.Fatal("Error opening existing dque ", err)
}
// Peek at the next item in the queue
item, err := q.Peek()
if err != nil {
if !errors.Is(err, dque.ErrEmpty) {
log.Fatal("Error peeking at item", err)
}
}
log.Println("Peeked at:", item)
// Dequeue the next item in the queue
item, err = q.Dequeue()
if err != nil && !errors.Is(err, dque.ErrEmpty) {
log.Fatal("Error dequeuing item:", err)
}
log.Println("Dequeued an item:", item)
log.Println("Size should be zero:", q.Size())
go func() {
if enqErr := q.Enqueue(&Item{"Joe", 1}); enqErr != nil {
log.Fatal("Error enqueueing item", enqErr)
}
}()
// Dequeue the next item in the queue and block until one is available
item, err = q.DequeueBlock()
if err != nil {
log.Fatal("Error dequeuing item ", err)
}
doSomething(item)
}
func doSomething(item *Item) {
fmt.Println("Dequeued:", item)
}
Output: Dequeued: &{Joe 1}
func NewOrOpen ¶
NewOrOpen either creates a new queue for items of type T, or opens an existing durable queue.
func (*DQue[T]) Close ¶
Close releases the lock on the queue rendering it unusable for further usage by this instance. Close will return an error if it has already been called.
func (*DQue[T]) Dequeue ¶
Dequeue removes and returns the first item in the queue. When the queue is empty, nil and dque.ErrEmpty are returned.
On error, the returned object may still be non-nil and valid — it was successfully dequeued but subsequent cleanup (segment deletion or creation) failed. Callers should process the returned object even when err != nil.
func (*DQue[T]) DequeueBlock ¶
DequeueBlock behaves similar to Dequeue, but is a blocking call until an item is available.
func (*DQue[T]) DiskBytes ¶ added in v0.9.0
DiskBytes returns an estimate of disk usage for the queue in bytes by summing the sizes of all segment files in the queue directory. Returns 0 when the queue is closed or on any filesystem error.
func (*DQue[T]) Peek ¶
Peek returns the first item in the queue without dequeueing it. When the queue is empty, nil and dque.ErrEmpty are returned. Do not use this method with multiple dequeueing threads or you may regret it.
func (*DQue[T]) PeekBlock ¶
PeekBlock behaves similar to Peek, but is a blocking call until an item is available.
func (*DQue[T]) SegmentNumbers ¶
SegmentNumbers returns the number of both the first and last segment. There is likely no use for this information other than testing.
func (*DQue[T]) Size ¶
Size locks things up while calculating so you are guaranteed an accurate size... unless you have changed the itemsPerSegment value since the queue was last empty. Then it could be wildly inaccurate.
func (*DQue[T]) SizeUnsafe ¶
SizeUnsafe returns the approximate number of items in the queue. Use Size() if having the exact size is important to your use-case.
The return value could be wildly inaccurate if the itemsPerSegment value has changed since the queue was last empty. Also, because the value is taken under lock, the size may change after returning from this method.
func (*DQue[T]) Turbo ¶
Turbo returns true if the turbo flag is on. Having turbo on speeds things up significantly.
func (*DQue[T]) TurboOff ¶
TurboOff re-enables the "safety" mode that syncs every file change to disk as they happen. If turbo is already off an error is returned
type ErrCorruptedSegment ¶
ErrCorruptedSegment is returned when a segment file cannot be opened due to inconsistent formatting. Recovery may be possible by clearing or deleting the file, then reloading using dque.New().
func (ErrCorruptedSegment) Error ¶
func (e ErrCorruptedSegment) Error() string
Error returns a string describing ErrCorruptedSegment
func (ErrCorruptedSegment) Unwrap ¶
func (e ErrCorruptedSegment) Unwrap() error
Unwrap returns the wrapped error
type ErrUnableToDecode ¶
ErrUnableToDecode is returned when an object cannot be decoded.
func (ErrUnableToDecode) Error ¶
func (e ErrUnableToDecode) Error() string
Error returns a string describing ErrUnableToDecode error
func (ErrUnableToDecode) Unwrap ¶
func (e ErrUnableToDecode) Unwrap() error
Unwrap returns the wrapped error