1

我正在使用 Puma 服务器来实现多线程。这是我的控制器:

class PhoneCallsController < ActionController::Base
  include ActionController::Live
  protect_from_forgery :except => :record_call

  # GET: Return messages to JavaScript pop-up
  def get_messages
      random_num = rand(65536)
      log "Start of get_messages, random id = #{random_num}"
      sleep 60
      #while session[:new_record_date]==session[:prev_record_date] do
      #  sleep 1
      #end
      session[:prev_record_date] = session[:new_record_date]
      render :status => :ok, :json => ['my message']
      log "End of get_messages, random id = #{random_num}"
  end

  # POST: Record a phone call. Called by PBX.
  def record_call
    log 'Start of record_call'

    data = Hash.from_xml(request.raw_post)
    pbx_data = data['PbxData']

    pc = PhoneCall.new({
                            :command => pbx_data['cmd'].strip,
                            :recipient_ip => pbx_data['RecipientIP'].strip,
                            :phone_num => pbx_data['PhoneNum'].strip
                        })
    pc.save!

    session[:new_record_date] = pc.created_at

    debug_text = "call received:\ncmd: #{pc.command}\nRecipientIP: #{pc.recipient_ip}\nPhoneNum: #{pc.phone_num}"

    log debug_text
    render :status => :ok, :text => debug_text

    log 'End of record_call'
  end

  # Test page to simulate PBX calls
  def call_test
  end

  # Test page to receive pop-up notifications
  def messages_test
  end

  private
  def log(msg)
    Rails.logger.info msg
    puts msg
  end
end

因此,有两个主要方法:get_messages由 JavaScript 调用,其任务是在电话到达之前不返回结果(应保持连接)。

第二种方法 -record_call在接听电话时由 PBX 脚本调用。

问题是——当只有

sleep 60

get_messages在then方法中提到record_call可以随时调用,并且整个 allpication 没有被锁定。

但是,如果我将其替换sleep 60

while session[:new_record_date]==session[:prev_record_date] do
  sleep 1
end

(应该如此) - 这个while循环阻塞了整个应用程序。

我究竟做错了什么?为什么sleep不阻止应用程序,但是当它被包装成while循环(假设它是一个无限循环)时,应用程序被锁定了?

我想我的情况下的多线程不是真正的多线程,sleep而是以特殊方式处理。

4

0 回答 0