meridian

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

README

Meridian

Go Reference Build Status Go Report Card Latest Release License

A Go library of concurrency utilities.

Features

  • Promise and Future
  • SingleFlight

Installation

Run the go get command to install Meridian:

go get github.com/AndreySenov/meridian

Use the -u flag to update Meridian to the latest version:

go get -u github.com/AndreySenov/meridian

Promise and Future

A Promise and a Future are companion constructs used to handle results of asynchronous tasks. The Promise produces the result at most once. The Future provides a read-only interface to consume the result. Any number of Future handles can observe the outcome of the same Promise.

Usage example:

func GetProfile(ctx context.Context, id string) (*Profile, error) {
	p := meridian.NewPromise[*Profile]()

	go func() {
		r, err := fetchProfileFromDB(id)
		p.Complete(r, err) // or p.Resolve(r) / p.Reject(err)
	}()

	f := p.Future()
	return f.Get(ctx) // blocks until completed or ctx is done
}

SingleFlight

SingleFlight is an alternative to golang.org/x/sync/singleflight with generic keys and values.

While a task for a key is in flight, every Do call with that key joins it and receives the same result instead of running its own task:

var flights meridian.SingleFlight[string, *Profile]

func LoadProfile(ctx context.Context, id string) (*Profile, error) {
	future := flights.Do(id, func() (*Profile, error) {
		return fetchProfileFromDB(id) // runs once per key, no matter how many callers
	})
	return future.Get(ctx) // each caller waits with its own context
}

Documentation

See the package documentation for the full API reference.

License

Meridian is licensed under the Apache License, Version 2.0. See NOTICE and LICENSE for details.

Documentation

Overview

Package meridian provides concurrency utilities: Promise and Future to handle results of asynchronous tasks, and SingleFlight to deduplicate concurrent calls.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Future

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

Future is a read handle for a Promise's eventual result, created by Promise.Future. Futures are small values, safe to copy and to share between goroutines. The zero value has no Promise behind it, and its methods panic.

func (Future[T]) Done

func (f Future[T]) Done() <-chan struct{}

Done returns a channel that is closed when the Promise is completed.

func (Future[T]) Get

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

Get returns the result, blocking until the Promise is completed or ctx is done. If ctx ends first, Get returns the zero value and ctx.Err(); if both are ready, the result wins. Get may be called repeatedly.

func (Future[T]) IsShared

func (f Future[T]) IsShared() bool

IsShared reports whether other Future handles exist for the same Promise. When true, the result value is shared: if T is a pointer, slice, or map, mutating the value affects the other holders, so treat it as read-only.

type Promise

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

Promise is the writable side of an asynchronous result: it is completed at most once, and the outcome is delivered to every Future handle created from it. Create a Promise with NewPromise and use it by pointer; copying a Promise is unsafe.

func NewPromise

func NewPromise[T any]() *Promise[T]

NewPromise returns a new, pending Promise.

func (*Promise[T]) Complete

func (p *Promise[T]) Complete(value T, err error)

Complete completes the Promise with value and err. Only the first completion takes effect: later calls to Complete, Resolve, or Reject are no-ops. Safe for concurrent use.

func (*Promise[T]) Future

func (p *Promise[T]) Future() Future[T]

Future returns a new read handle for the Promise's eventual result. It may be called any number of times, before or after completion; every handle observes the same outcome.

func (*Promise[T]) Reject

func (p *Promise[T]) Reject(err error)

Reject completes the Promise with err. It is equivalent to Complete with a zero value and err.

func (*Promise[T]) Resolve

func (p *Promise[T]) Resolve(value T)

Resolve completes the Promise successfully with value. It is equivalent to Complete(value, nil).

type SingleFlight

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

SingleFlight deduplicates concurrent work by key: while a task for a key is in flight, every Do call with that key joins it and receives the same result instead of running its own task. The zero value is ready to use.

It is a typed alternative to golang.org/x/sync/singleflight: keys and values are generic rather than string and interface{}, so results need no type assertions. Each caller gets a Future that it can await under its own context. A panicking task is reported to every waiter as a regular error.

func (*SingleFlight[K, V]) Do

func (s *SingleFlight[K, V]) Do(key K, task func() (V, error)) Future[V]

Do returns a Future for the result of the task, either starting the task in a new goroutine or joining the in-flight call for the key if one exists. Future.IsShared indicates whether the result is shared by multiple callers. The task runs to completion even if every caller stops waiting. A panic inside the task is recovered and delivered to all waiters as an error; a task that terminates its goroutine with runtime.Goexit also yields an error instead of blocking the waiters.

func (*SingleFlight[K, V]) Forget

func (s *SingleFlight[K, V]) Forget(key K)

Forget detaches the current call for the key, if any, without interrupting it: callers already waiting still receive its result, while subsequent Do calls for the key start a fresh task.

Jump to

Keyboard shortcuts

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