// lesson: channel-semaphores

Backpressure by Construction

A buffered channel is a semaphore: capacity = permits, send = acquire, receive = release. That makes a bounded blocking queue the most honest data structure in concurrent programming โ€” when the consumer falls behind, the producer physically stops. No unbounded slices quietly eating your heap.

The hard part is never the happy path; it's shutdown. Three rules make a closeable queue coherent:

  • Only the closer decides "no more input". Put after close is an error, and a Put blocked at close time must wake up and get that error too.
  • Items already accepted are owed to consumers: after close, Get drains whatever remains before reporting "done".
  • Every blocked party must be woken by Close. Forget one waiter and you have a goroutine leak that only shows up in production.

You can build this on channels plus a done-channel, or on sync.Mutex + sync.Cond (two conditions: "not full" and "not empty"; re-check the predicate in a loop after every Wait; Broadcast on close). Both work. Pick one and get the edge cases right.

โ€บ Bounded Blocking Queue

30 pts

Implement a generic FIFO queue:

var ErrClosed = errors.New("queue: closed") // keep this exported variable

func NewQueue[T any](capacity int) *Queue[T]
func (q *Queue[T]) Put(v T) error
func (q *Queue[T]) Get() (T, bool)
func (q *Queue[T]) Close()

Required semantics (capacity is always >= 1 in the tests; Close is called at most once):

  • Put blocks while the queue holds capacity items. It returns nil on success and ErrClosed if the queue is closed โ€” including when the call was already blocked on a full queue when Close happened.
  • Get blocks while the queue is empty and open. It returns (item, true) in FIFO order; after Close it keeps returning buffered items until the queue is drained, then returns (zero, false). A Get blocked on an empty queue when Close happens returns (zero, false).
  • Close wakes every blocked Put and Get. Nothing stays parked.
  • Everything must be safe under many concurrent producers and consumers.

Log in to submit a solution and earn points.