Question

Trying something out I'm not very familiar with:

require 'sinatra'
require 'redis'

$redis = # Connect Redis
$log = []

Thread.new do
  while true do
    $redis.set 'test', $log.pop
  end
end

post '/' do
    $log.push(request.user_agent)
    "ok"
end

Say that I get a couple of thousand hits per second to /. What happens if push and pop are called simultaneously on $log?

Will raising the priority of the worker thread help anything?

Was it helpful?

Solution

You should use use a Queue for this, as it is meant for cross-thread communication. It is thread-safe, and keeps the Thread from busy-waiting as Queue#pop will suspend the thread if there is nothing on the queue instead of looping till the OS takes control away.

require 'redis'
require 'sinatra'
require 'thread'

$redis = # Connect Redis
$log = Queue.new

Thread.new do
  while entry = $log.pop
    $redis.set 'test', entry
  end
end

post '/' do
  $log.push(request.user_agent)
  "ok"
end

However, what you have won’t be an issue (as far as unexpected results go—performance will be a problem) because of MRI’s GIL (other Ruby implementations without a GIL may have issues, though). Also, it would be best to avoid using global variables.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top