6
0
mirror of https://git.mills.io/prologic/msgbus.git synced 2024-06-27 09:19:04 +00:00
prologic-msgbus/options.go
James Mills 6bfb669347 Add support for a write-ahead-log (WAL) to persist messages (#33)
Closes #31

Adds support for a write-ahead-log (WAL) for messages per queue/topic. This is now the new default behaviour and adds a new CLI flag `-l/--log-path` and Env var `LOG_PATH` to configure where the logs are stored.

On startup, the message bus will refill the queues with the contents of messages from persisted log files with the most recent `-Q/--max-queue-size` number of items.

That is, on startup/crash the queues/topics will always contain the same messages as if the message bus had never restarted or crashed in the first place.

This has a benefit of actually making the per-topic sequence number _actually_ monotic increasing integers and something that can be relied upon when indexing into a queue/topic for subscribers with the `-i/--index` / `Index` option.

Co-authored-by: James Mills <prologic@shortcircuit.net.au>
Reviewed-on: https://git.mills.io/prologic/msgbus/pulls/33
2022-04-03 15:59:38 +00:00

105 lines
2.2 KiB
Go

package msgbus
import (
"fmt"
"os"
"github.com/tidwall/wal"
)
const (
// DefaultBind is the default bind address
DefaultBind = ":8000"
// DefaultLogPath is the default path to write logs to (wal)
DefaultLogPath = "./logs"
// DefaultMaxQueueSize is the default maximum size of queues
DefaultMaxQueueSize = 1024 // ~8MB per queue (1000 * 4KB)
// DefaultMaxPayloadSize is the default maximum payload size
DefaultMaxPayloadSize = 8192 // 8KB
// DefaultBufferLength is the default buffer length for subscriber chans
DefaultBufferLength = 256
// DefaultMetrics is the default for whether to enable metrics
DefaultMetrics = false
// DefaultNoSync is the default for whether to disable faync after writing
// messages to the write-ahead-log (wal) files. The default is `false` which
// is safer and will prevent corruption in event of crahses or power failure,
// but is slower.
DefaultNoSync = false
)
var DefaultOptions = &Options{
LogPath: DefaultLogPath,
BufferLength: DefaultBufferLength,
MaxQueueSize: DefaultMaxQueueSize,
MaxPayloadSize: DefaultMaxPayloadSize,
Metrics: DefaultMetrics,
NoSync: DefaultNoSync,
}
// Options ...
type Options struct {
LogPath string
BufferLength int
MaxQueueSize int
MaxPayloadSize int
Metrics bool
NoSync bool
}
type Option func(opts *Options) error
func WithLogPath(logPath string) Option {
return func(opts *Options) error {
if err := os.MkdirAll(logPath, 0755); err != nil {
return fmt.Errorf("error creating log path %s: %w", logPath, err)
}
opts.LogPath = logPath
return nil
}
}
func WithBufferLength(bufferLength int) Option {
return func(opts *Options) error {
opts.BufferLength = bufferLength
return nil
}
}
func WithMaxQueueSize(maxQueueSize int) Option {
return func(opts *Options) error {
opts.MaxQueueSize = maxQueueSize
return nil
}
}
func WithMaxPayloadSize(maxPayloadSize int) Option {
return func(opts *Options) error {
opts.MaxPayloadSize = maxPayloadSize
return nil
}
}
func WithMetrics(metrics bool) Option {
return func(opts *Options) error {
opts.Metrics = metrics
return nil
}
}
func WithNoSync(noSync bool) Option {
return func(opts *Options) error {
wal.DefaultOptions.NoSync = noSync
return nil
}
}