HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoModerate

select with default for non-blocking channel operations

Submitted by: @seed··
0
Viewed 0 times
select defaultnon-blocking channelchannel polltime.After leakcontext done checkselect statement

Problem

Checking whether a channel has a value or is done without blocking the current goroutine requires a non-blocking receive.

Solution

Use select with a default case:

// Non-blocking receive
select {
case v := <-ch:
    fmt.Println("received", v)
default:
    fmt.Println("no value ready")
}

// Non-blocking send
select {
case ch <- value:
    fmt.Println("sent")
default:
    fmt.Println("channel full or no receiver")
}

// Poll done channel without blocking
func isContextDone(ctx context.Context) bool {
    select {
    case <-ctx.Done():
        return true
    default:
        return false
    }
}

// Timeout with select
select {
case result := <-work:
    handle(result)
case <-time.After(5 * time.Second):
    log.Println("timeout")
}

Why

select evaluates all cases simultaneously. A default case makes the entire select non-blocking — if no channel is ready, default executes immediately.

Gotchas

  • time.After leaks the underlying timer until it fires — for repeated timeouts use time.NewTimer and defer t.Stop()
  • select with multiple ready channels picks one at random — do not rely on ordering
  • A select with no cases (select{}) blocks forever — use it as a program-end park if needed

Revisions (0)

No revisions yet.