goTx

package module
v0.0.0-...-aa2b4ad Latest Latest
Warning

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

Go to latest
Published: Apr 10, 2023 License: MIT Imports: 8 Imported by: 0

README

goTx

goTx is a simple and flexible Go library for managing transactions with rollback capabilities. It provides an easy way to append update and rollback functions, and then execute them in order, while handling errors and rollbacks when necessary. The package supports synchronous and asynchronous execution, and offers retry options for retrying failed transactions.

Features

  • Sequential or asynchronous execution of update functions
  • Automatic rollback in case of failure
  • Optional retry functionality with configurable backoff strategies
  • Customizable error handling

Installation

To install the goTx package, simply run the following command:

go get github.com/yourusername/goTx

Usage

To use the goTx package, start by importing it:

import (
	"github.com/interwubs/goTx"
)

Create a new Saga transaction:

saga := goTx.NewSagaTx()

Or create a new Saga transaction with custom options:

customRetryOptions := &goTx.RetryOptions{
	MaxRetries: 5,
	Backoff: &goTx.ConstantBackoff{
		Interval: 2 * time.Second,
	},
	UnrecoverableErrors: []error{customErr1, customErr2},
}

saga := goTx.NewSagaTx(
	goTx.WithAsync(false),
	goTx.WithRetries(customRetryOptions),
)

Append update functions and their corresponding rollback functions:

saga.Append(func() error {
	// Perform update operation
	return nil
}, func() error {
	// Perform rollback operation
	return nil
})

Execute all update functions in order, and handle rollbacks if necessary:

updateErrors, compensateErrors := saga.ExecuteAll()
if updateErrors != nil {
	// Handle update errors
}
if compensateErrors != nil {
	// Handle rollback errors
}

For more control over error handling, you can use the Do function:

updateErrors, compensateErrors := saga.Do(updateFunc3, rollbackFunc3)
if updateErrors != nil {
    // Handle update errors
}
if compensateErrors != nil {
    // Handle rollback errors
}

Retries

goTx provides an optional retry feature for executing update functions. You can enable retries and customize the retry configuration by providing a RetryOptions struct with custom settings.

Retry Options
  • MaxRetries: The maximum number of retries for each update function
  • Backoff: The backoff strategy used between retries (implements the Backoff interface)
  • UnrecoverableErrors: A list of errors that should not be retried
Backoff Strategies

goTx supports different backoff strategies:

  • ConstantBackoff: A constant time interval between retries
  • ExponentialBackoff: An exponentially increasing time interval between retries with an optional random jitter factor

Example

Here's a complete example of using the goTx package:

package main

import (
	"context"
	"fmt"

	"github.com/interwubs/goTx"
)

func main() {
	saga := goTx.NewSagaTx()

	var count int

	// Increment count by 1
	saga.Append(func() error {
		count++
		return nil
	}, func() error {
		count--
		return nil
	})

	// Increment count by 2
	saga.Append(func() error {
		count += 2
		return nil
	}, func() error {
		count -= 2
		return nil
	})

	// Trigger rollback
	saga.Append(func() error {
		return fmt.Errorf("update error")
	}, func() error {
		return nil
	})

	updateErrs, rollbackErrs := saga.ExecuteAll(context.Background())
	fmt.Printf("Update error: %v\n", updateErrs)
	fmt.Printf("Rollback error: %v\n", rollbackErrs)
	fmt.Printf("Final count: %d\n", count)
}

This example creates a SagaTx instance, appends two update functions that increment a count variable, and then triggers a rollback. The rollback functions undo the increment operations, resulting in a final count value of 0.

License

goTx is licensed under the MIT License. See the LICENSE file for more information.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Retry

func Retry(fn func() error, options *RetryOptions) error

Types

type Backoff

type Backoff interface {
	NextInterval() time.Duration
}

type CompensateFunc

type CompensateFunc func() error

type ConstantBackoff

type ConstantBackoff struct {
	Interval time.Duration
}

func (*ConstantBackoff) NextInterval

func (b *ConstantBackoff) NextInterval() time.Duration

type ExponentialBackoff

type ExponentialBackoff struct {
	InitialInterval time.Duration
	MaxInterval     time.Duration
	Multiplier      float64
	RandomFactor    float64
	CurrentInterval time.Duration
}

func (*ExponentialBackoff) NextInterval

func (b *ExponentialBackoff) NextInterval() time.Duration

type RetryOptions

type RetryOptions struct {
	MaxRetries int
	Backoff    Backoff

	UnrecoverableErrors []error
}

func (*RetryOptions) AppendUnrecoverableErrors

func (t *RetryOptions) AppendUnrecoverableErrors(errs ...error)

type SagaTx

type SagaTx struct {
	*RetryOptions
	// contains filtered or unexported fields
}

func NewSagaTx

func NewSagaTx(options ...SagaTxOption) *SagaTx

func (*SagaTx) Append

func (t *SagaTx) Append(txFunc UpdateFunc, rollbackFunc CompensateFunc)

func (*SagaTx) Do

func (t *SagaTx) Do(txFunc UpdateFunc, rollbackFunc CompensateFunc) (updateErrors error, compensateErrors error)

func (*SagaTx) ExecuteAll

func (t *SagaTx) ExecuteAll(ctx context.Context) (updateErrors error, compensateErrors error)

type SagaTxOption

type SagaTxOption func(*SagaTx)

func WithAsync

func WithAsync(async bool) SagaTxOption

func WithRetries

func WithRetries(retryOptions *RetryOptions) SagaTxOption

type Transactor

type Transactor interface {
	Append(txFunc UpdateFunc, rollbackFunc CompensateFunc)
	Do(txFunc UpdateFunc, rollbackFunc CompensateFunc) (updateErrors error, compensateErrors error)
	ExecuteAll(ctx context.Context) (updateErrors error, compensateErrors error)
}

type UpdateFunc

type UpdateFunc func() error

Jump to

Keyboard shortcuts

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