Remember_me
Remember_me

Reputation: 283

Unicorn server worker config

I've just seen a unicorn server config like this, in my new project codebase :

worker_processes ENV['UNICORN_WORKERS'].to_i || 2
preload_app true
timeout 30

after_fork do |server, worker|
  Thread.new do
    begin
      RABBIT_CONNECTION = Bunny.new(ENV['AMQP_URL'])
      RABBIT_CONNECTION.start
    rescue Bunny::TCPConnectionFailed => e
      puts "Connection failed"
    end
    begin
      OUTGOING_CHANNEL = RABBIT_CONNECTION.create_channel
    rescue Bunny::PreconditionFailed => e
      puts "Channel-level exception! Code: #{e.channel_close.reply_code},
      message: #{e.channel_close.reply_text}".squish
    ensure
      RABBIT_CONNECTION.close
    end
  end
end

From what I know about unicorn is that it is a single-threaded, multi-process web server.

What does this Thread.do block do? What would happen if all this other code was there without being surrounded in the Thread.do block?

Upvotes: 0

Views: 480

Answers (1)

Vishnu J
Vishnu J

Reputation: 491

Yes unicorn is a single-threaded, multi-process web server. Here, the Thread.do is being used to asynchronously connect to RabbitMQ using the Bunny client. That is, unicorn doesn't wait for the RabbitMQ connection after creating the process. A thread would wait for the same.

In Unicorn (or MRI ruby for that matter) only one thread can use the CPU at a time. This is accomplished using something called the GIL or the Global Interpreter Lock.

Read this: http://www.jstorimer.com/blogs/workingwithcode/8085491-nobody-understands-the-gil

And this: https://en.wikipedia.org/wiki/Global_interpreter_lock

However, for IO ops like waiting for a connection to the RabbitMQ server, this thread will not use up the CPU cycles and other threads can run on the CPU.

If Thread.do wasn't there, and the RabbitMQ server is unreachable, the process would wait for the server to be available or the connection times out.

Upvotes: 3

Related Questions