inbox

package
v0.0.0-...-339bc34 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2026 License: GPL-3.0 Imports: 12 Imported by: 0

README

inbox

platform/inbox is the canonical home for durable consumer attempt lifecycle primitives in speed.

Usage contract

  • Call inbox.Execute from your consumer handler.
  • Provide an inbox.Store implementation that persists attempt state.
  • Use inbox.NewMySQLStore when you want the built-in GORM/MySQL adapter for event_consume_log.
  • Configure retry and dead-letter callbacks in the caller; this package does not bind storage, metrics, or broker defaults.
result, err := inbox.Execute(ctx, txManager, store, consumerName, delivery, handler, inbox.ExecuteOptions{
	MaxAttempts:     5,
	InitialBackoff:  time.Second,
	ProcessingLease: 5 * time.Minute,
})
_ = result

Documentation

Index

Constants

View Source
const (
	StatusPending      = "pending"
	StatusProcessing   = "processing"
	StatusRetrying     = "retrying"
	StatusSucceeded    = "succeeded"
	StatusDeadLettered = "dead_lettered"
)
View Source
const MySQLTableName = defaultMySQLTableName

Variables

View Source
var (
	ErrMissingConsumerName    = errors.New("consumer_name is required")
	ErrMissingEventID         = errors.New("event_id is required")
	ErrMissingSourceTopic     = errors.New("source_topic is required")
	ErrMissingBrokerMessageID = errors.New("broker_message_id is required")
	ErrEventConflict          = errors.New("event_id was already consumed with a different payload")
	ErrEventInProgress        = errors.New("event is still processing")
)
View Source
var MySQLSchemaSQL string

Functions

func HashPayload

func HashPayload(payload string) string

Types

type AttemptStart

type AttemptStart struct {
	Record    Record
	Decision  StartDecision
	Delay     time.Duration
	Reclaimed bool
}

type DBProvider

type DBProvider func(context.Context) *gorm.DB

type Delivery

type Delivery struct {
	EventID         string
	SourceTopic     string
	BrokerMessageID string
	Payload         string
	MessageMetadata map[string]string
}

type ExecuteOptions

type ExecuteOptions struct {
	MaxAttempts       int
	InitialBackoff    time.Duration
	MaxBackoff        time.Duration
	BackoffMultiplier float64
	ProcessingLease   time.Duration
	OnReclaim         func(ctx context.Context, record Record)
	OnRetry           func(ctx context.Context, record Record, delay time.Duration, cause error)
	OnSuccess         func(ctx context.Context, record Record)
	OnSkip            func(ctx context.Context, record Record)
	OnDeadLetter      func(ctx context.Context, record Record) error
}

type ExecuteResult

type ExecuteResult struct {
	Outcome     Outcome
	Record      Record
	Reclaimed   bool
	Attempted   int
	DeadLetter  bool
	LastBackoff time.Duration
}

func Execute

func Execute(
	ctx context.Context,
	tx kernel.TransactionManager,
	store Store,
	consumerName string,
	delivery Delivery,
	fn func(ctx context.Context) error,
	options ExecuteOptions,
) (ExecuteResult, error)

type MySQLSchema

type MySQLSchema struct {
	TableName string
}

type MySQLStore

type MySQLStore struct {
	// contains filtered or unexported fields
}

func NewMySQLStore

func NewMySQLStore(db *gorm.DB, schema MySQLSchema) *MySQLStore

func (*MySQLStore) CountByStatus

func (s *MySQLStore) CountByStatus(ctx context.Context, consumerName string) (map[string]int64, error)

func (*MySQLStore) DeleteSucceededBefore

func (s *MySQLStore) DeleteSucceededBefore(ctx context.Context, before time.Time, limit int) (int64, error)

func (*MySQLStore) Get

func (s *MySQLStore) Get(ctx context.Context, consumerName string, eventID string) (Record, error)

func (*MySQLStore) ListByStatus

func (s *MySQLStore) ListByStatus(ctx context.Context, consumerName, status string) ([]Record, error)

func (*MySQLStore) MarkDeadLettered

func (s *MySQLStore) MarkDeadLettered(ctx context.Context, id int64, lastError string, deadLetteredAt time.Time) error

func (*MySQLStore) MarkRetrying

func (s *MySQLStore) MarkRetrying(ctx context.Context, id int64, lastError string, nextAttemptAt time.Time) error

func (*MySQLStore) MarkSucceeded

func (s *MySQLStore) MarkSucceeded(ctx context.Context, id int64, finishedAt time.Time) error

func (*MySQLStore) OldestActionableAge

func (s *MySQLStore) OldestActionableAge(ctx context.Context, consumerName string) (time.Duration, error)

func (*MySQLStore) OldestAgeByStatus

func (s *MySQLStore) OldestAgeByStatus(ctx context.Context, consumerName string) (map[string]time.Duration, error)

func (*MySQLStore) Redrive

func (s *MySQLStore) Redrive(ctx context.Context, consumerName string, eventID string) error

func (*MySQLStore) StartAttempt

func (s *MySQLStore) StartAttempt(
	ctx context.Context,
	consumerName string,
	delivery Delivery,
	payloadHash string,
	maxAttempts int,
	lease time.Duration,
) (AttemptStart, error)

type Outcome

type Outcome string
const (
	OutcomeProcessed    Outcome = "processed"
	OutcomeSkipped      Outcome = "skipped"
	OutcomeDeadLettered Outcome = "dead_lettered"
)

type ProviderStore

type ProviderStore struct {
	// contains filtered or unexported fields
}

func NewProviderStore

func NewProviderStore(dbProvider DBProvider, schema MySQLSchema) *ProviderStore

func (*ProviderStore) CountByStatus

func (s *ProviderStore) CountByStatus(ctx context.Context, consumerName string) (map[string]int64, error)

func (*ProviderStore) DeleteSucceededBefore

func (s *ProviderStore) DeleteSucceededBefore(ctx context.Context, before time.Time, limit int) (int64, error)

func (*ProviderStore) Get

func (s *ProviderStore) Get(ctx context.Context, consumerName string, eventID string) (Record, error)

func (*ProviderStore) ListByStatus

func (s *ProviderStore) ListByStatus(ctx context.Context, consumerName, status string) ([]Record, error)

func (*ProviderStore) MarkDeadLettered

func (s *ProviderStore) MarkDeadLettered(ctx context.Context, id int64, lastError string, deadLetteredAt time.Time) error

func (*ProviderStore) MarkRetrying

func (s *ProviderStore) MarkRetrying(ctx context.Context, id int64, lastError string, nextAttemptAt time.Time) error

func (*ProviderStore) MarkSucceeded

func (s *ProviderStore) MarkSucceeded(ctx context.Context, id int64, finishedAt time.Time) error

func (*ProviderStore) OldestActionableAge

func (s *ProviderStore) OldestActionableAge(ctx context.Context, consumerName string) (time.Duration, error)

func (*ProviderStore) OldestAgeByStatus

func (s *ProviderStore) OldestAgeByStatus(ctx context.Context, consumerName string) (map[string]time.Duration, error)

func (*ProviderStore) Redrive

func (s *ProviderStore) Redrive(ctx context.Context, consumerName string, eventID string) error

func (*ProviderStore) StartAttempt

func (s *ProviderStore) StartAttempt(
	ctx context.Context,
	consumerName string,
	delivery Delivery,
	payloadHash string,
	maxAttempts int,
	lease time.Duration,
) (AttemptStart, error)

type Record

type Record struct {
	ID              int64
	ConsumerName    string
	EventID         string
	SourceTopic     string
	Payload         string
	MessageMetadata map[string]string
	BrokerMessageID string
	PayloadHash     string
	Status          string
	AttemptCount    int32
	MaxAttempts     int32
	NextAttemptAt   time.Time
	LeaseExpiresAt  time.Time
	LastError       string
	DeadLetteredAt  time.Time
	FinishedAt      time.Time
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

type StartDecision

type StartDecision string
const (
	DecisionProcess StartDecision = "process"
	DecisionSkip    StartDecision = "skip"
	DecisionWait    StartDecision = "wait"
)

type Store

type Store interface {
	StartAttempt(
		ctx context.Context,
		consumerName string,
		delivery Delivery,
		payloadHash string,
		maxAttempts int,
		lease time.Duration,
	) (AttemptStart, error)
	MarkSucceeded(ctx context.Context, id int64, finishedAt time.Time) error
	MarkRetrying(ctx context.Context, id int64, lastError string, nextAttemptAt time.Time) error
	MarkDeadLettered(ctx context.Context, id int64, lastError string, deadLetteredAt time.Time) error
	Get(ctx context.Context, consumerName string, eventID string) (Record, error)
}

Jump to

Keyboard shortcuts

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