Offer items into a bounded sized queue with nonblocking pushes and report the remaining capacity as open, tight, or full.

bounded capacity A `SizedQueue` has fixed capacity, so `push(item, true)` buffers an item when there is room and raises `ThreadError` when the queue is full. The accepted and rejected counts describe how much shared capacity remains for producers.

Sized Queue Capacity Coordination Report

offered
sized_queue_capacity_coordination_report.rb
Replay: real traced execution (multi-file project)
offered = 2
capacity = 2
buffer = SizedQueue.new(capacity)
accepted = 0
rejected = 0

offered.times do |item|
  begin
    buffer.push(item, true)
    accepted += 1
  rescue ThreadError
    rejected += 1
  end
end

remaining = capacity - buffer.size

status = if rejected > 0
  "full"
elsif remaining == 0
  "tight"
else
  "open"
end

puts "offered=#{offered}"
puts "accepted=#{accepted}"
puts "remaining=#{remaining}"
puts "status=#{status}"
offered = 1
capacity = 2
buffer = SizedQueue.new(capacity)
accepted = 0
rejected = 0

offered.times do |item|
  begin
    buffer.push(item, true)
    accepted += 1
  rescue ThreadError
    rejected += 1
  end
end

remaining = capacity - buffer.size

status = if rejected > 0
  "full"
elsif remaining == 0
  "tight"
else
  "open"
end

puts "offered=#{offered}"
puts "accepted=#{accepted}"
puts "remaining=#{remaining}"
puts "status=#{status}"
offered = 4
capacity = 2
buffer = SizedQueue.new(capacity)
accepted = 0
rejected = 0

offered.times do |item|
  begin
    buffer.push(item, true)
    accepted += 1
  rescue ThreadError
    rejected += 1
  end
end

remaining = capacity - buffer.size

status = if rejected > 0
  "full"
elsif remaining == 0
  "tight"
else
  "open"
end

puts "offered=#{offered}"
puts "accepted=#{accepted}"
puts "remaining=#{remaining}"
puts "status=#{status}"
  1. offered ← 2, capacity ← 2, buffer ← ⟨Thread::SizedQueue A⟩, accepted ← 0

    1offered→ 2 = 2  #@offered=1, 42capacity→ 2 = 23buffer→ ⟨Thread::SizedQueue A⟩ = SizedQueue.new(capacity2)4accepted→ 0 = 05rejected→ 0 = 067offered2.times do |item|8  begin9    buffer.push(item, true)10    accepted += 111  rescue ThreadError12    rejected += 113  end14end
  2. do |item|

    pass 1 of 2
    7offered.times do |item0|8  begin9    buffer.push(item, true)
  3. do |item|

    pass 2 of 2
    7offered2.times do |item1|8  begin9    buffer.push(item, true)10    accepted += 111  rescue ThreadError12    rejected += 113  end14end
  4. remaining ← 0, status ← tight

    16remaining→ 0 = capacity2 - buffer.size21718status→ tight = if rejected0 > 019  "full"20elsif remaining0 == 021  "tight"22else23  "open"24end2526puts "offered=#{offered2}"27puts "accepted=#{accepted2}"28puts "remaining=#{remaining0}"29puts "status=#{statustight}"
    outputoffered=2
    accepted=2
    remaining=0
    status=tight
  1. offered ← 1, capacity ← 2, buffer ← ⟨Thread::SizedQueue A⟩, accepted ← 0

    1offered→ 1 = 12capacity→ 2 = 23buffer→ ⟨Thread::SizedQueue A⟩ = SizedQueue.new(capacity2)4accepted→ 0 = 05rejected→ 0 = 067offered1.times do |item|8  begin9    buffer.push(item, true)10    accepted += 111  rescue ThreadError12    rejected += 113  end14end
  2. do |item|

    7offered1.times do |item0|8  begin9    buffer.push(item, true)10    accepted += 111  rescue ThreadError12    rejected += 113  end14end
  3. remaining ← 1, status ← open

    16remaining→ 1 = capacity2 - buffer.size11718status→ open = if rejected0 > 019  "full"20elsif remaining1 == 021  "tight"22else23  "open"24end2526puts "offered=#{offered1}"27puts "accepted=#{accepted1}"28puts "remaining=#{remaining1}"29puts "status=#{statusopen}"
    outputoffered=1
    accepted=1
    remaining=1
    status=open
  1. offered ← 4, capacity ← 2, buffer ← ⟨Thread::SizedQueue A⟩, accepted ← 0

    1offered→ 4 = 42capacity→ 2 = 23buffer→ ⟨Thread::SizedQueue A⟩ = SizedQueue.new(capacity2)4accepted→ 0 = 05rejected→ 0 = 067offered4.times do |item|8  begin9    buffer.push(item, true)10    accepted += 111  rescue ThreadError12    rejected += 113  end14end
  2. do |item|

    pass 1 of 4
    7offered.times do |item0|8  begin9    buffer.push(item, true)
    All 4 passes — pass 1 is the card above
    passitemoffered
    10
    21
    32
    434
  3. remaining ← 0, status ← full

    16remaining→ 0 = capacity2 - buffer.size21718status→ full = if rejected2 > 019  "full"20elsif remaining0 == 021  "tight"22else23  "open"24end2526puts "offered=#{offered4}"27puts "accepted=#{accepted2}"28puts "remaining=#{remaining0}"29puts "status=#{statusfull}"
    outputoffered=4
    accepted=2
    remaining=0
    status=full