rungroup

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2024 License: Apache-2.0 Imports: 4 Imported by: 0

README

rungroup

A Go module for managing concurrent tasks with automatic cancellation when any task completes or fails.

Go Reference Go Report Card

rungroup is a Go module that provides a way to manage and synchronize concurrent tasks. Its primary feature is the ability to cancel all goroutines when any one of them completes. This package is particularly useful for scenarios where you need to run multiple operations concurrently but want to stop all of them as soon as any one operation completes or fails.

Features

  • Manage multiple goroutines as a group
  • Automatic cancellation of all tasks when one completes
  • Support for timeouts
  • Easy-to-use API

Installation

To install the rungroup module, use go get:

go get github.com/goaux/rungroup

Usage

Here's a basic example of how to use the rungroup module:

package main

import (
    "context"
    "fmt"
    "time"

    "github.com/goaux/rungroup"
	"github.com/goaux/timer"
)

func main() {
	// Create a new group with no timeout
	rg := rungroup.New(context.Background())

	// Add tasks to the group
	rg.Go(func(ctx context.Context) error {
		if err := timer.Sleep(ctx, 150*time.Millisecond); err != nil {
			fmt.Println("task1 canceled")
			return err
		}
		fmt.Println("task1 done")
		return nil
	})

	rg.Go(func(ctx context.Context) error {
		if err := timer.Sleep(ctx, 300*time.Millisecond); err != nil {
			fmt.Println("task2 canceled")
			return err
		}
		fmt.Println("task2 done")
		return nil
	})

	// Wait for all tasks to complete or be canceled
	err := rg.Wait()
	if err != nil {
		fmt.Printf("must not error: %v\n", err)
	} else {
		fmt.Println("ok")
	}
}

In this example, the first task completes after 150 milliseconds, which triggers the cancellation of the second task. The Wait method returns when all tasks have either completed or been canceled.

API

New(ctx context.Context) *Group

Creates a new Group with the given context.

NewTimeout(ctx context.Context, d time.Duration) *Group

Creates a new Group with the given context and timeout duration.

(g *Group) Go(task func(context.Context) error)

Starts a new goroutine in the Group.

(g *Group) Wait() error

Blocks until all tasks in the Group have completed or been canceled.

(g *Group) Cancel()

Explicitly cancels the Group's context, causing all tasks to be interrupted.

Note

  • A Group must be created by New or NewTimeout, zero value must not be used.
  • A Group must not be copied after first use.
  • A Group must not be reused after calling Wait.

Documentation

Overview

Package rungroup provides a way to manage and synchronize concurrent tasks.

Its primary feature is the ability to cancel all goroutines when any one of them completes. This package is particularly useful for scenarios where you need to run multiple operations concurrently, but want to stop all of them as soon as any one operation completes or fails.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/goaux/rungroup"
	"github.com/goaux/timer"
)

func main() {
	// Create a new group with no timeout
	rg := rungroup.New(context.Background())

	// Add tasks to the group
	rg.Go(func(ctx context.Context) error {
		if err := timer.Sleep(ctx, 150*time.Millisecond); err != nil {
			fmt.Println("task1 canceled")
			return err
		}
		fmt.Println("task1 done")
		return nil
	})

	rg.Go(func(ctx context.Context) error {
		if err := timer.Sleep(ctx, 300*time.Millisecond); err != nil {
			fmt.Println("task2 canceled")
			return err
		}
		fmt.Println("task2 done")
		return nil
	})

	// Wait for all tasks to complete or be canceled
	err := rg.Wait()
	if err != nil {
		fmt.Printf("must not error: %v\n", err)
	} else {
		fmt.Println("ok")
	}
}
Output:
task1 done
task2 canceled
ok

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Group

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

Group represents a collection of goroutines working on subtasks that are part of the same overall task. The Group is designed to manage concurrent execution and provides automatic cancellation of all running tasks when any single task completes.

  • A Group must be created by New or NewTimeout, zero value must not be used.
  • A Group must not be copied after first use.
  • A Group must not be reused after calling Wait.

func New

func New(ctx context.Context) *Group

New creates a new Group with the given context. The returned Group's context is canceled when the first task completes (returns), regardless of whether it returns an error or nil. This cancellation triggers the termination of all other running tasks in the group.

func NewTimeout

func NewTimeout(ctx context.Context, d time.Duration) *Group

NewTimeout creates a new Group with the given context and timeout duration. The returned Group's context is canceled when the timeout expires, or when the first task completes (returns), whichever happens first. This cancellation triggers the termination of all other running tasks in the group.

The timeout is implemented as a separate task within the group, ensuring consistent behavior with other tasks.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/goaux/rungroup"
	"github.com/goaux/timer"
)

func main() {
	// Create a new group with a 300-milliseconds timeout
	rg := rungroup.NewTimeout(context.Background(), 300*time.Millisecond)

	// Add tasks to the group
	rg.Go(func(ctx context.Context) error {
		if err := timer.Sleep(ctx, 500*time.Millisecond); err != nil {
			fmt.Println("task1 canceled")
			return err
		}
		fmt.Println("task1 done")
		return nil
	})

	rg.Go(func(ctx context.Context) error {
		if err := timer.Sleep(ctx, 150*time.Millisecond); err != nil {
			fmt.Println("task2 canceled")
			return err
		}
		fmt.Println("task2 done")
		return nil
	})

	// Wait for all tasks to complete or be canceled
	err := rg.Wait()
	if err != nil {
		fmt.Printf("must not error: %v\n", err)
	} else {
		fmt.Println("ok")
	}
}
Output:
task2 done
task1 canceled
ok

func (*Group) Cancel

func (g *Group) Cancel()

Cancel explicitly cancels the Group's context, causing all tasks to be interrupted. This method can be used to manually trigger the cancellation of all running tasks.

func (*Group) Go

func (g *Group) Go(task func(context.Context) error)

Go starts a new goroutine in the Group. The provided function is executed in its own goroutine. If this function completes (either by returning nil or an error), it will trigger the cancellation of the Group's context, causing all other running tasks to be terminated.

Go will panic if called on a Group that has already been used (i.e., after Wait has been called).

func (*Group) Wait

func (g *Group) Wait() error

Wait blocks until all tasks in the Group have completed or been cancelled. It returns the first non-nil error (if any) from any of the tasks. If a task completes without error, Wait will still trigger the cancellation of all other tasks before returning.

If Wait is called without any tasks being started using the Go method, it returns nil immediately. Even in this case, the Group cannot be reused.

Jump to

Keyboard shortcuts

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