safechan

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 23, 2026 License: MIT Imports: 3 Imported by: 0

README

go-safechan

CI Go Reference License

Safe channel utilities for Go with panic-free send/receive, context-aware communication, and combinators

Installation

go get github.com/philiprehberger/go-safechan

Usage

Safe Send (no panic on closed channel)
import "github.com/philiprehberger/go-safechan"

ch := make(chan int, 1)
ok := safechan.Send(ch, 42) // true

close(ch)
ok = safechan.Send(ch, 1) // false, no panic
Context-aware Send
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

ch := make(chan int)
ok := safechan.SendCtx(ctx, ch, 42) // false if ctx expires or ch is closed
Context-aware Receive
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

val, ok := safechan.RecvCtx(ctx, ch) // returns zero value and false on timeout
Fan-In (merge channels)
merged := safechan.FanIn(ch1, ch2, ch3)
for val := range merged {
    fmt.Println(val)
}
Fan-Out (round-robin distribution)
outputs := safechan.FanOut(input, 3)
// Values from input are distributed round-robin to outputs[0], outputs[1], outputs[2]
Broadcast (send to all)
outputs := safechan.Broadcast(input, 3)
// Every value from input is sent to all 3 output channels
Drain (collect remaining values)
ch := make(chan int, 10)
ch <- 1
ch <- 2
ch <- 3

vals := safechan.Drain(ch) // [1 2 3], non-blocking

// With context support:
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
vals = safechan.DrainCtx(ctx, ch) // stops on context cancellation
Filter / Map (channel transformers)
// Filter: keep only even numbers
evens := safechan.Filter(numbers, func(n int) bool { return n%2 == 0 })
for val := range evens {
    fmt.Println(val)
}

// Map: transform values
doubled := safechan.Map(numbers, func(n int) int { return n * 2 })
for val := range doubled {
    fmt.Println(val)
}

// Map with type conversion
strs := safechan.Map(numbers, func(n int) string { return fmt.Sprintf("%d", n) })
Timeout Send / Receive
ch := make(chan int)

// Send with deadline
ok := safechan.SendTimeout(ch, 42, 100*time.Millisecond) // false if timed out

// Receive with deadline
val, ok := safechan.RecvTimeout(ch, 100*time.Millisecond) // zero + false if timed out

API

Function Description
Send[T](ch, val) Safe send; returns false instead of panicking on closed channel
SendCtx[T](ctx, ch, val) Context-aware send; returns false on cancellation or closed channel
Recv[T](ch) Receive with ok flag
RecvCtx[T](ctx, ch) Context-aware receive; returns zero + false on cancellation
Drain[T](ch) Non-blocking read of all buffered values
DrainCtx[T](ctx, ch) Context-aware drain; stops on cancellation
Filter[T](ch, pred) Forward only values matching predicate
Map[T, R](ch, fn) Transform each value through a function
SendTimeout[T](ch, val, d) Send with timeout; returns false on expiry
RecvTimeout[T](ch, d) Receive with timeout; returns zero + false on expiry
FanIn[T](channels...) Merge multiple channels into one
FanOut[T](ch, n) Distribute values round-robin to n channels
Broadcast[T](ch, n) Send each value to all n channels

Development

go test ./...
go vet ./...

License

MIT

Documentation

Overview

Package safechan provides safe channel utilities for Go.

It offers panic-free send operations, context-aware channel communication, and channel combinators such as fan-in, fan-out, and broadcast.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Broadcast

func Broadcast[T any](ch <-chan T, n int) []<-chan T

Broadcast sends each value from the input channel to all n output channels. Every output channel receives every value. All output channels are closed when the input channel is closed.

func Drain added in v0.2.0

func Drain[T any](ch <-chan T) []T

Drain reads all remaining values from ch without blocking. It returns the collected values immediately when no more values are available in the channel buffer.

func DrainCtx added in v0.2.0

func DrainCtx[T any](ctx context.Context, ch <-chan T) []T

DrainCtx reads all remaining values from ch, stopping when the context is cancelled or no more values are available in the channel buffer.

func FanIn

func FanIn[T any](channels ...<-chan T) <-chan T

FanIn merges multiple input channels into a single output channel. The output channel is closed when all input channels have been closed. Values are forwarded as they arrive from any input channel.

func FanOut

func FanOut[T any](ch <-chan T, n int) []<-chan T

FanOut distributes values from a single input channel to n output channels in a round-robin fashion. All output channels are closed when the input channel is closed.

func Filter added in v0.2.0

func Filter[T any](in <-chan T, pred func(T) bool) <-chan T

Filter returns a new channel that only forwards values from in that satisfy the predicate. A background goroutine reads from in and writes matching values to the output channel. The output channel is closed when the input channel is closed.

func Map added in v0.2.0

func Map[T, R any](in <-chan T, fn func(T) R) <-chan R

Map returns a new channel that transforms each value from in using fn. A background goroutine reads from in, applies fn, and writes the result to the output channel. The output channel is closed when the input channel is closed.

func Recv

func Recv[T any](ch <-chan T) (val T, ok bool)

Recv receives a value from ch. It returns the value and true if a value was received, or the zero value and false if the channel is closed. This is a thin wrapper around the built-in receive for API consistency.

func RecvCtx

func RecvCtx[T any](ctx context.Context, ch <-chan T) (val T, ok bool)

RecvCtx receives a value from ch, respecting context cancellation. It returns the value and true if a value was received, or the zero value and false if the context was done or the channel is closed.

func RecvTimeout added in v0.2.0

func RecvTimeout[T any](ch <-chan T, d time.Duration) (T, bool)

RecvTimeout receives a value from ch with a timeout duration. It returns the value and true if a value was received, or the zero value and false if the deadline expired before a value was available.

func Send

func Send[T any](ch chan<- T, val T) (sent bool)

Send sends val on ch without panicking if ch is closed. It returns true if the value was sent successfully, or false if the channel was closed (recovering the panic internally).

func SendCtx

func SendCtx[T any](ctx context.Context, ch chan<- T, val T) bool

SendCtx sends val on ch, respecting context cancellation. It returns true if the value was sent successfully, or false if the context was done or the channel was closed.

func SendTimeout added in v0.2.0

func SendTimeout[T any](ch chan<- T, val T, d time.Duration) bool

SendTimeout sends val on ch with a timeout duration. It returns true if the value was sent successfully, or false if the deadline expired before the send could complete.

Types

This section is empty.

Jump to

Keyboard shortcuts

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