Ruby Sinatra与使用者线程和作业队列

问题描述:

我正在尝试创建一个非常简单的静态服务器.当它收到请求时,我想在队列上创建一个新作业,该作业可以由另一个线程处理,而当前线程将响应返回给客户端.

I’m trying to create a very simple restful server. When it receives a request, I want to create a new job on a queue that can be handled by another thread while the current thread returns a response to the client.

我看了看Sinatra,但是距离还不算太远.

I looked at Sinatra, but haven't got too far.

require 'sinatra'
require 'thread'

queue = Queue.new

set :port, 9090

get '/' do
  queue << 'item'
  length = queue.size
  puts 'QUEUE LENGTH %d', length
  'Message Received'
end

consumer = Thread.new do
  5.times do |i|
    value = queue.pop(true) rescue nil
    puts "consumed #{value}"
  end
end

consumer.join

在上面的示例中,我知道使用者线程只会运行几次(与应用程序的生命周期相对),但是即使这样对我也不起作用.

In the above example, I know the consumer thread would only run a few times (as opposed to the life of the application), but even this isn't working for me.

有更好的方法吗?

您的主要问题是您致电

Your main problem is your call to Queue#pop. You’re passing true, which causes it not to suspend the thread and raises an exception instead, which you rescue with nil. Your consumer thread therefore loops five times before any thing else can happen.

您需要将该行更改为

value = queue.pop

,以便线程等待将新数据推送到队列中.

so that the thread waits for new data being pushed onto the queue.

您还需要从最后删除consumer.join行,因为一旦将呼叫更改为pop,这将导致死锁.

You’ll also need to remove the consumer.join line from the end, since that will cause deadlock once you’ve changed the call to pop.

(此外,这也不是您的主要问题的一部分,但看起来您想要 printf 而不是puts,当您打印队列长度时.

(Also, it’s not part of your main problem, but it looks like you want printf rather than puts when you print the queue length).