chanx

package
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 3 Imported by: 1

Documentation

Overview

Package chanx provides paradigmatic goroutine communication: observable values, subjects, and cancelable subscriptions over channels.

This is the communication axis of the concx toolkit (alongside nest for lifecycle and schedx for orchestration). Prefer this module path over the archived github.com/xoctopus/x/chanx package.

Key types:

A nil cancel cause is normalized to ErrCompleted.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrCompleted = errors.New("completed")
)

Functions

This section is empty.

Types

type Cancelable

type Cancelable interface {
	CancelCause(err error)
}

type NotifiableObserver

type NotifiableObserver[T any] interface {
	Observer[T]
	ValueNotifier[T]
}
Example
package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/xoctopus/concx/pkg/chanx"
)

func main() {
	// Create a NotifiableObserver
	obs := chanx.NewNotifiableObserver[int]()

	var wg sync.WaitGroup

	// Start a producer goroutine
	wg.Go(func() {
		obs.Send(1)
		obs.Send(2)
		obs.Send(3)
		time.Sleep(10 * time.Millisecond)
		// Cancel after sending all data. A nil error will be converted to ErrCompleted.
		obs.CancelCause(nil)
	})

	// Consume data in the main goroutine until the channel is closed
	for v := range obs.Value() {
		fmt.Println("Received:", v)
	}

	wg.Wait()

	// Check the final error state
	fmt.Println("Error:", obs.Err())

}
Output:
Received: 1
Received: 2
Received: 3
Error: completed

func NewNotifiableObserver

func NewNotifiableObserver[T any]() NotifiableObserver[T]

type Observable

type Observable[T any] interface {
	Observe() Observer[T]
}

type Observer

type Observer[T any] interface {
	ValueObserver[T]
	Cancelable

	Done() <-chan struct{}
	Err() error
}

type ObserverFunc

type ObserverFunc[T any] func() Observer[T]

func (ObserverFunc[T]) Observe

func (f ObserverFunc[T]) Observe() Observer[T]

type Subject

type Subject[T any] struct {
	// contains filtered or unexported fields
}
Example
package main

import (
	"fmt"
	"slices"
	"sync"
	"time"

	"github.com/xoctopus/x/iterx"

	"github.com/xoctopus/concx/pkg/chanx"
)

func main() {
	// Create a Subject
	subject := &chanx.Subject[int]{}

	// Create two observers
	obs1 := subject.Observe()
	obs2 := subject.Observe()

	var (
		wg      sync.WaitGroup
		results = make(chan string, 4)
	)

	consuming := func(name string, observer chanx.Observer[int]) func() {
		return func() {
			for v := range observer.Value() {
				results <- fmt.Sprintf("%s received: %d", name, v)
			}
		}
	}

	// Consumer 1
	wg.Go(consuming("obs1", obs1))
	// Consumer 2
	wg.Go(consuming("obs2", obs2))

	// Producer broadcasts data via the Subject
	subject.Send(1)
	time.Sleep(10 * time.Millisecond)
	subject.Send(2)
	time.Sleep(10 * time.Millisecond)

	// Close the Subject, which cascades the cancellation to all subscribers
	subject.CancelCause(nil)
	// Wait for all consumers to finish
	wg.Wait()
	close(results)

	for _, s := range slices.Sorted(iterx.Recv(results)) {
		fmt.Println(s)
	}

	// Verify the error state of the Subject and its Observers
	fmt.Println("Subject Error:", subject.Err())
	fmt.Println("Obs1 Error:", obs1.Err())
	fmt.Println("Obs2 Error:", obs2.Err())

}
Output:
obs1 received: 1
obs1 received: 2
obs2 received: 1
obs2 received: 2
Subject Error: completed
Obs1 Error: completed
Obs2 Error: completed

func (*Subject[T]) CancelCause

func (s *Subject[T]) CancelCause(err error)

func (*Subject[T]) Done

func (s *Subject[T]) Done() <-chan struct{}

func (*Subject[T]) Err

func (s *Subject[T]) Err() error

func (*Subject[T]) Observe

func (s *Subject[T]) Observe() Observer[T]

func (*Subject[T]) Send

func (s *Subject[T]) Send(x T)

func (*Subject[T]) Subscribe

func (s *Subject[T]) Subscribe(o Subscriber[T])

type Subscriber

type Subscriber[T any] interface {
	ValueNotifier[T]
	Cancelable

	Done() <-chan struct{}
	Err() error
}

type ValueNotifier

type ValueNotifier[T any] interface {
	Send(x T)
}

type ValueObserver

type ValueObserver[T any] interface {
	Value() <-chan T
}

Jump to

Keyboard shortcuts

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