inbox

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package inbox implements the idempotent-consumer pattern: a dedup table that lets a consumer process each message exactly once under at-least-once delivery. It is the consumer-side complement to the outbox package.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Migrate

func Migrate(ctx context.Context, db *bun.DB) error

Migrate creates the inbox table if it does not exist.

func Once

func Once(ctx context.Context, db *bun.DB, messageID string, fn func(ctx context.Context, tx bun.Tx) error) error

Once runs fn exactly once for messageID. It inserts a dedup marker and runs fn in a single transaction: a messageID already recorded skips fn and returns nil; if fn returns an error the transaction (marker included) rolls back, so the message can be reprocessed later. For that guarantee, fn must perform its work through the provided tx.

Example

Process a message exactly once, even if it is delivered twice (at-least-once).

package main

import (
	"context"
	"database/sql"
	"fmt"

	"github.com/uptrace/bun"
	"github.com/uptrace/bun/dialect/sqlitedialect"
	"github.com/uptrace/bun/driver/sqliteshim"

	"github.com/rahmadafandi/fibr/inbox"
)

func main() {
	sqldb, _ := sql.Open(sqliteshim.ShimName, "file::memory:?cache=shared")
	db := bun.NewDB(sqldb, sqlitedialect.New())
	defer db.Close()
	ctx := context.Background()
	_ = inbox.Migrate(ctx, db)

	handle := func(_ context.Context, _ bun.Tx) error {
		fmt.Println("processing order.created")
		return nil
	}

	// Same message delivered twice.
	_ = inbox.Once(ctx, db, "order.created:42", handle)
	_ = inbox.Once(ctx, db, "order.created:42", handle)
}
Output:
processing order.created

func Prune added in v1.6.0

func Prune(ctx context.Context, db bun.IDB, olderThan time.Duration) (int64, error)

Prune deletes markers processed more than olderThan ago and returns how many were removed. Markers are never deleted otherwise; keep them for at least as long as a message can still be redelivered.

Types

type Entry

type Entry struct {
	bun.BaseModel `bun:"table:inbox,alias:ib"`

	MessageID   string    `bun:"message_id,pk"`
	ProcessedAt time.Time `bun:"processed_at,notnull"`
}

Entry is one processed-message marker.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL