semgroup

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2020 License: MIT Imports: 4 Imported by: 0

README

semgroup

Test codecov Go Report Card GoDoc

semgroup provides a simple wrapper around an error group that adds the ability to limit the maximum number of in-flight goroutines working on a group of tasks via a weighted semaphore. The API is exactly the same as the errgroup package.

Getting Started

Get the latest version of the package with go get

go get -u github.com/mwalto7/semgroup

Example

package main

import (
    "context"
    "fmt"
    "log"
    "runtime"
    "time"

    "github.com/mwalto7/semgroup"
)

func main() {
    // Create a new group with a maximum of 10 in-flight goroutines.
    sg, ctx := semgroup.WithContext(context.Background(), 10)

    // At most 10 goroutines will print "subtask <i>" between sleeps.
    for i := 0; i < 100; i++ {
        i := i
        sg.Go(func() error {
            select {
            case <-ctx.Done():
                return ctx.Err()
            default:
                fmt.Printf("subtask %d\n", i)
            }
            time.Sleep(2 * time.Second)
            return nil
        })
    }

    // Wait for all goroutines to finish, propagating the first non-nil error (if-any).
    if err := sg.Wait(); err != nil {
        log.Fatal(err)
    }
}

Documentation

Overview

Package semgroup provides a modified errgroup.Group with the ability to limit the maximum concurrent access of resources for groups of goroutines working on subtasks of a common task.

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 is an errgroup.Group combined with a semaphore. The maximum number of in-flight goroutines is equal to the weight of the semaphore.

A zero Group is invalid. Use WithContext to initialize a Group.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/mwalto7/semgroup"
)

func main() {
	// Create a new group with a maximum of 10 in-flight goroutines.
	sg, ctx := semgroup.WithContext(context.Background(), 10)

	// At most 10 goroutines will print "subtask <i>" between sleeps.
	for i := 0; i < 100; i++ {
		i := i
		sg.Go(func() error {
			select {
			case <-ctx.Done():
				return ctx.Err()
			default:
				fmt.Printf("subtask %d\n", i)
			}
			time.Sleep(2 * time.Second)
			return nil
		})
	}

	// Wait for all goroutines to finish, propagating the first non-nil error (if-any).
	if err := sg.Wait(); err != nil {
		log.Fatal(err)
	}
}
Output:

func WithContext

func WithContext(ctx context.Context, n int64) (*Group, context.Context)

WithContext returns a new Group with a weighted semaphore with weight n and an associated Context derived from ctx.

If the given Context is nil, context.Background is used.

If the given semaphore weight n is less than or equal to zero, runtime.NumCPU()*2 is used.

func (*Group) Go

func (sg *Group) Go(f func() error)

Go blocks until a semaphore is acquired, then calls the given function in a new goroutine. If a non-nil error is returned when acquiring the semaphore, the error is returned and the group is cancelled.

See errgroup for details on error handling and propagation.

func (*Group) Wait

func (sg *Group) Wait() error

Wait blocks until all function calls from the Go method have returned, then returns the first non-nil error (if any) from them.

func (*Group) Weight

func (sg *Group) Weight() int64

Weight returns weight of the Group's semaphore, or the maximum allowed number of in-flight goroutines.

Jump to

Keyboard shortcuts

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