runnable

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2024 License: MIT Imports: 6 Imported by: 0

README

runnable

Overview

runnable is a Go package that provides a Runnable interface for functions or objects that can be started and stopped. It provides a simple way to run a function or object in a goroutine and stop it when needed. It also provides a way to run a function with retry and statistics number of restarts, when started and stopped, if returned error, etc.

Examples

Runnable Function
fmt.Println("Simple function...")
err := runnable.New(func(ctx context.Context) error {
    fmt.Println("Starting...")
    defer fmt.Println("Stopping...")

    for i := 0; i < 5; i++ {
        select {
        case <-ctx.Done():
            return nil
        default:
        }
        time.Sleep(1 * time.Second)
        fmt.Println("Running...")
    }
    return nil
}).Run(context.Background())
if err != nil {
    fmt.Println(err)
}
Runnable Function with Stop
fmt.Println("Simple function with stop...")
r := runnable.New(func(ctx context.Context) error {
    fmt.Println("Starting...")
    defer fmt.Println("Stopping...")

    for {
        select {
        case <-ctx.Done():
            return nil
        default:
        }
        time.Sleep(1 * time.Second)
        fmt.Println("Running...")
    }
})

go func() {
    time.Sleep(5 * time.Second)

    fmt.Println("Calling Stop...")
    err := r.Stop(context.Background())
    if err != nil {
        fmt.Println(err)
    }
}()

err = r.Run(context.Background())
if err != nil {
    fmt.Println(err)
}
Runnable Function with timeout
fmt.Println("Simple function with timeout...")
ctxWithTimeout, _ := context.WithTimeout(context.Background(), 5*time.Second)
err = runnable.New(func(ctx context.Context) error {
    fmt.Println("Starting...")
    defer fmt.Println("Stopping...")

    for {
        select {
        case <-ctx.Done():
            return nil
        default:
        }
        time.Sleep(1 * time.Second)
        fmt.Println("Running...")
    }
}).Run(ctxWithTimeout)
if err != nil {
    fmt.Println(err)
}
Runnable Function with retry
fmt.Println("Simple function with retry...")
errorReturned := false
err = runnable.New(func(ctx context.Context) error {
    fmt.Println("Starting...")
    defer fmt.Println("Stopping...")
    
    if !errorReturned {
        errorReturned = true
        return fmt.Errorf("error")
    }
    
    // do something
    for i := 0; i < 5; i++ {
        select {
        case <-ctx.Done():
            return nil
        default:
        }
        time.Sleep(1 * time.Second)
        fmt.Println("Running...")
    }
    return nil
}, runnable.WithRetry(3, runnable.ResetNever)).Run(context.Background())
if err != nil {
    fmt.Println(err)
}
Runnable Object
package main

import (
	"time"

	"github.com/0xsequence/runnable"
)

type Monitor struct {
	runnable.Runnable
}

func NewMonitor() *Monitor {
	m := &Monitor{}
	m.Runnable = runnable.New(m.run)
	return m
}

func (m *Monitor) run(ctx context.Context) error {
	fmt.Println("Starting...")
	defer fmt.Println("Stopping...")
	
	// Start monitoring
	for {
		select {
		case <-ctx.Done():
			return nil
		default:
		}

		time.Sleep(1 * time.Second)
		fmt.Println("Monitoring...")
	}
	return nil
}

func main() {
	fmt.Println("Runnable object(Monitor)...")
	m := NewMonitor()

	go func() {
		time.Sleep(5 * time.Second)

		fmt.Println("Calling Stop...")
		err := m.Stop(context.Background())
		if err != nil {
			fmt.Println(err)
		}
	}()

	err = m.Run(context.Background())
	if err != nil {
		fmt.Println(err)
	}
}

Documentation

Index

Constants

View Source
const ResetNever time.Duration = 0

Variables

View Source
var (
	ErrAlreadyRunning = fmt.Errorf("already running")
	ErrNotRunning     = fmt.Errorf("not running")
)

Functions

This section is empty.

Types

type Option

type Option interface {
	// contains filtered or unexported methods
}

func WithRetry

func WithRetry(maxRetries int, resetAfter time.Duration) Option

func WithStatus added in v0.0.2

func WithStatus(id string, store *StatusStore) Option

type Runnable

type Runnable interface {
	Run(ctx context.Context) error
	Stop(ctx context.Context) error
	IsRunning() bool
}

func New

func New(runFunc func(ctx context.Context) error, options ...Option) Runnable

New creates a new Runnable with the given runFunc.

Example:

type Monitor struct {
	runnable.Runnable
}

func (m *Monitor) run(ctx context.Context) error {
	// do something
	return nil
}

func NewMonitor() Monitor {
	m := Monitor{}
	m.Runnable = runnable.NewRunnable(m.run)
	return m
}

func NewGroup

func NewGroup(runners ...Runnable) Runnable

NewGroup creates a new Runnable that runs multiple runnables concurrently.

Example:

group := NewGroup(
	New(func(ctx context.Context) error {
		// do something
		return nil
	}),
	New(func(ctx context.Context) error {
		// do something
		return nil
	}),
)

err := group.Run(context.Background())
if err != nil {
	// handle error
}

type Status added in v0.0.2

type Status struct {
	Running   bool       `json:"running"`
	Restarts  int        `json:"restarts"`
	StartTime time.Time  `json:"start_time"`
	EndTime   *time.Time `json:"end_time,omitempty"`
	LastError error      `json:"last_error"`
}

type StatusMap added in v0.0.2

type StatusMap map[string]Status

type StatusStore added in v0.0.2

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

func NewStatusStore added in v0.0.2

func NewStatusStore() *StatusStore

func (*StatusStore) Get added in v0.0.2

func (s *StatusStore) Get() StatusMap

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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