xsync

package
v0.15.3 Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2024 License: MIT Imports: 5 Imported by: 4

Documentation

Overview

Package xsync contains extensions to the standard library package sync.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Lazy deprecated

func Lazy[T any](f func() T) func() T

Lazy makes a lazily-initialized value. On first access, it uses f to create the value. Later accesses all receive the same value.

Deprecated: sync.OnceValue is in the standard library as of Go 1.21.

Example
var (
	expensive = Lazy(func() string {
		fmt.Println("doing expensive init")
		return "foo"
	})
)

fmt.Println(expensive())
fmt.Println(expensive())
Output:

doing expensive init
foo
foo

Types

type ContextCond

type ContextCond struct {
	L sync.Locker
	// contains filtered or unexported fields
}

ContextCond is equivalent to sync.Cond, except its Wait function accepts a context.Context.

ContextConds should not be copied after first use.

func NewContextCond

func NewContextCond(l sync.Locker) *ContextCond

NewContextCond returns a new ContextCond with l as its Locker.

func (*ContextCond) Broadcast

func (c *ContextCond) Broadcast()

Broadcast wakes all goroutines blocked in Wait(), if there are any.

It is allowed but not required for the caller to hold c.L during the call.

func (*ContextCond) Signal

func (c *ContextCond) Signal()

Signal wakes one goroutine blocked in Wait(), if there is any. No guarantee is made as to which goroutine will wake.

It is allowed but not required for the caller to hold c.L during the call.

func (*ContextCond) Wait

func (c *ContextCond) Wait(ctx context.Context) error

Wait is equivalent to sync.Cond.Wait, except it accepts a context.Context. If the context expires before this goroutine is woken by Broadcast or Signal, it returns ctx.Err() immediately. If an error is returned, does not reaquire c.L before returning.

type Future

type Future[T any] struct {
	// contains filtered or unexported fields
}

Future can be filled with a value exactly once. Many goroutines can concurrently wait for it to be filled. After filling, Wait() immediately returns the value it was filled with.

Futures must be created by NewFuture and should not be copied after first use.

func NewFuture

func NewFuture[T any]() *Future[T]

NewFuture returns a ready-to-use Future.

func (*Future[T]) Fill

func (f *Future[T]) Fill(x T)

Fill fills f with value x. All active calls to Wait return x, and all future calls to Wait return x immediately.

Panics if f has already been filled.

func (*Future[T]) Wait

func (f *Future[T]) Wait() T

Wait waits for f to be filled with a value and returns it. Returns immediately if f is already filled.

func (*Future[T]) WaitContext

func (f *Future[T]) WaitContext(ctx context.Context) (T, error)

Wait waits for f to be filled with a value and returns it, or returns ctx.Err() if ctx expires before this happens. Returns immediately if f is already filled.

type Group

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

Group manages a group of goroutines.

func NewGroup

func NewGroup(ctx context.Context) *Group

NewGroup returns a Group ready for use. The context passed to any of the f functions will be a descendant of ctx.

func (*Group) Do added in v0.13.0

func (g *Group) Do(f func(ctx context.Context))

Do calls f once from another goroutine.

func (*Group) Periodic

func (g *Group) Periodic(
	interval time.Duration,
	jitter time.Duration,
	f func(ctx context.Context),
)

Periodic spawns a goroutine that calls f once per interval +/- jitter.

func (*Group) PeriodicOrTrigger

func (g *Group) PeriodicOrTrigger(
	interval time.Duration,
	jitter time.Duration,
	f func(ctx context.Context),
) func()

PeriodicOrTrigger spawns a goroutine which calls f whenever the returned function is called. If f is already running when triggered, f will run again immediately when it finishes. Also calls f when it has been interval+/-jitter since the last trigger.

func (*Group) Stop

func (g *Group) Stop()

Stop cancels the context passed to spawned goroutines. After the group is stopped, no more goroutines will be spawned.

func (*Group) StopAndWait added in v0.13.0

func (g *Group) StopAndWait()

StopAndWait cancels the context passed to any of the spawned goroutines and waits for all spawned goroutines to exit. After the group is stopped, no more goroutines will be spawned.

func (*Group) Trigger

func (g *Group) Trigger(f func(ctx context.Context)) func()

Trigger spawns a goroutine which calls f whenever the returned function is called. If f is already running when triggered, f will run again immediately when it finishes.

type Map

type Map[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Map is a typesafe wrapper over sync.Map.

func (*Map[K, V]) CompareAndDelete added in v0.15.0

func (m *Map[K, V]) CompareAndDelete(key K, old V) (deleted bool)

func (*Map[K, V]) CompareAndSwap added in v0.15.0

func (m *Map[K, V]) CompareAndSwap(key K, old V, new V) (deleted bool)

func (*Map[K, V]) Delete

func (m *Map[K, V]) Delete(key K)

func (*Map[K, V]) Load

func (m *Map[K, V]) Load(key K) (value V, ok bool)

func (*Map[K, V]) LoadAndDelete

func (m *Map[K, V]) LoadAndDelete(key K) (value V, loaded bool)

func (*Map[K, V]) LoadOrStore

func (m *Map[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool)

func (*Map[K, V]) Range

func (m *Map[K, V]) Range(f func(key K, value V) bool)

func (*Map[K, V]) Store

func (m *Map[K, V]) Store(key K, value V)

func (*Map[K, V]) Swap added in v0.15.0

func (m *Map[K, V]) Swap(key K, value V) (previous V, loaded bool)

type Pool

type Pool[T any] struct {
	// contains filtered or unexported fields
}

Pool is a typesafe wrapper over sync.Pool.

func NewPool

func NewPool[T any](new_ func() T) Pool[T]

func (*Pool[T]) Get

func (p *Pool[T]) Get() T

func (*Pool[T]) Put

func (p *Pool[T]) Put(x T)

type Watchable added in v0.15.1

type Watchable[T any] struct {
	// contains filtered or unexported fields
}

Watchable contains a value. It is similar to an atomic.Pointer[T] but allows notifying callers that a new value has been set.

Example
start := time.Now()

var w Watchable[int]
w.Set(0)
go func() {
	for i := 1; i < 20; i++ {
		w.Set(i)
		fmt.Printf("set %d at %s\n", i, time.Since(start).Round(time.Millisecond))
		time.Sleep(5 * time.Millisecond)
	}
}()

for {
	v, changed := w.Value()
	if v == 19 {
		return
	}

	fmt.Printf("observed %d at %s\n", v, time.Since(start).Round(time.Millisecond))

	// Sleep for longer between iterations to show that we don't slow down the setter.
	time.Sleep(17 * time.Millisecond)

	<-changed
}
Output:

func (*Watchable[T]) Set added in v0.15.1

func (w *Watchable[T]) Set(t T)

Set sets the value in w and notifies callers of Value() that there is a new value.

func (*Watchable[T]) Value added in v0.15.1

func (w *Watchable[T]) Value() (T, chan struct{})

Value returns the current value inside w and a channel that will be closed when w is Set() to a newer value than the returned one.

If called before the first Set(), returns the zero value of T.

Normal usage has an observer waiting for new values in a loop:

for {
	v, changed := w.Value()

	// do something with v

	<-changed
}

Note that the value in w may have changed multiple times between successive calls to Value(), Value() only ever returns the last-set value. This is by design so that slow observers cannot block Set(), unlike sending values on a channel.

Jump to

Keyboard shortcuts

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