Files
web/worker/README.md

3.6 KiB

go-worker

A simple, reusable, production-ready background worker module for NATS JetStream in Go.

This module allows you to easily run reliable, concurrent background workers that consume messages from JetStream streams using pull-based subscriptions. It integrates seamlessly with the go-nats embedded/clustered NATS module and follows the same clean, functional-options pattern as the rest of your toolkit.

Features

  • Pull-based JetStream consumer with configurable batch fetching
  • Concurrent message processing (configurable workers)
  • Automatic stream and consumer creation (idempotent)
  • Configurable storage (Memory or File) for development vs production durability
  • Graceful shutdown with context cancellation and subscription draining
  • Explicit Ack/Nak handling with retry support
  • Custom logger injection
  • Works with embedded or external NATS servers

Installation

go get git.citc.tech/go/web/worker

Quick Start

package main

import (
    "context"
    "log/slog"
    "os"

    "git.citc.tech/go/web/nats"
    "git.citc.tech/go/web/worker"
)

func main() {
    logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))

    // Connect to NATS (embedded or external)
    nc, natsShutdown, err := nats.New()
    if err != nil {
        logger.Error("failed to connect to NATS", "error", err)
        os.Exit(1)
    }
    defer natsShutdown()

    // Create background worker
    w, err := worker.New(nc,
        worker.WithStream("ORDERS"),
        worker.WithConsumer("order-processor", "orders.process"),
        worker.WithHandler(func(ctx context.Context, msg *nats.Msg) error {
            logger.Info("processing order", "data", string(msg.Data))
            // Your business logic here
            return nil
        }),
        worker.WithConcurrency(5),
        worker.WithStorage(nats.FileStorage), // or MemoryStorage for dev
        worker.WithLogger(logger),
    )
    if err != nil {
        logger.Error("failed to create worker", "error", err)
        os.Exit(1)
    }

    // Run worker (blocks until shutdown signal)
    go w.Run()

    // Your main application (e.g. HTTP server) runs here...

    // On exit
    defer w.Shutdown()
}

Options

Option Description Default
WithStream(name) JetStream stream name required
WithConsumer(name, subject) Consumer name and filter subject required
WithDurable(name) Durable consumer name (if different from consumer) uses consumer name
WithHandler(h) Message processing function required
WithConcurrency(n) Number of concurrent goroutines 1
WithAckWait(d) Time to wait for acknowledgment 30s
WithMaxDeliver(n) Maximum delivery attempts 1
WithLogger(l) Custom slog logger slog.Default()
WithStorage(t) Stream storage type (MemoryStorage or FileStorage) FileStorage (safe)

Storage Types

  • nats.MemoryStorage — Fast, in-memory only (lost on restart). Great for dev/testing.
  • nats.FileStorage — Persistent on disk (survives restarts). Recommended for production.