Waitgroups in Ruby

Our first example demonstrates the usage of a concept similar to WaitGroups in Ruby. We’ll use the Thread class and a mutex to achieve similar functionality.

require 'thread'

# This is the function we'll run in every thread.
def worker(id)
  puts "Worker #{id} starting"
  
  # Sleep to simulate an expensive task.
  sleep(1)
  puts "Worker #{id} done"
end

# This mutex will be used to synchronize access to the counter
mutex = Mutex.new
counter = 0

threads = []

# Launch several threads
5.times do |i|
  threads << Thread.new do
    worker(i + 1)
    
    # Decrement the counter when the thread is done
    mutex.synchronize do
      counter -= 1
    end
  end
  
  # Increment the counter for each thread
  mutex.synchronize do
    counter += 1
  end
end

# Wait for all threads to finish
while counter > 0
  sleep 0.1
end

puts "All workers completed"

In this Ruby example, we’re using threads to perform concurrent work. Here’s a breakdown of what’s happening:

  1. We define a worker function that simulates some work by sleeping for a second.

  2. We create a mutex and a counter to keep track of active threads.

  3. We launch 5 threads, each running the worker function.

  4. For each thread, we increment a counter before it starts and decrement it when it finishes.

  5. In the main thread, we wait until the counter reaches zero, indicating all threads have completed.

This approach mimics the behavior of WaitGroups in Go, allowing us to wait for multiple threads to finish before proceeding.

To run the program:

$ ruby waitgroups.rb
Worker 1 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 5 starting
Worker 1 done
Worker 2 done
Worker 3 done
Worker 4 done
Worker 5 done
All workers completed

The order of workers starting up and finishing is likely to be different for each invocation.

Note that while this approach works, Ruby has other concurrency primitives that might be more idiomatic depending on your specific use case, such as the concurrent-ruby gem which provides more advanced concurrency tools.