Single thread still handles concurrency request?

独自空忆成欢 提交于 2019-12-07 16:51:55

问题


Ruby process is single thread. When we start a single process using thin server, why are we still able to handle concurrency request?

require 'sinatra'
require 'thin'
set :server, %w[thin]

get '/test' do
  sleep 2   <----
  "success"
end

What is inside thin that can handle concurrency request? If it is due to event-machine framework, the code above is actually a sync code which is not for EM used.


回答1:


Quoting the chapter: "Non blocking IOs/Reactor pattern" in http://merbist.com/2011/02/22/concurrency-in-ruby-explained/: "this is the approach used by Twisted, EventMachine and Node.js. Ruby developers can use EventMachine or an EventMachine based webserver like Thin as well as EM clients/drivers to make non blocking async calls."

The heart of the matter regard EventMachine.defer * used for integrating blocking operations into EventMachine's control flow. The action of defer is to take the block specified in the first parameter (the "operation") and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.

When the operation completes, it will pass the result computed by the block (if any) back to the EventMachine reactor. Then, EventMachine calls the block specified in the second parameter to defer (the "callback"), as part of its normal event handling loop.

The result computed by the operation block is passed as a parameter to the callback. You may omit the callback parameter if you don't need to execute any code after the operation completes. *

Essentially, in response to an HTTP request, the server executes that you wrote, invokes the process method in the Connecction class. have a look at the code in $GEM_HOME/gems/thin-1.6.2/lib/thin/connection.rb:

# Connection between the server and client.
# This class is instanciated by EventMachine on each new connection
# that is opened.
class Connection < EventMachine::Connection
# Called when all data was received and the request
# is ready to be processed.
def process
  if threaded?
    @request.threaded = true
    EventMachine.defer(method(:pre_process), method(:post_process))
  else
    @request.threaded = false
    post_process(pre_process)
  end
end

..here is where a threaded connection invoke EventMachine.defer

The reactor

To see where is activated the EventMachine reactor should follow the initialization of the program: Notice that for all Sinatra applications and middleware ($GEM_HOME/gems/sinatra-1.4.5/base.rb) can run the Sinatra app as a self-hosted server using Thin, Puma, Mongrel, or WEBrick.

  def run!(options = {}, &block)
    return if running?
    set options
    handler         = detect_rack_handler
  ....

the method detect_rack_handler returns the first Rack::Handler

 return Rack::Handler.get(server_name.to_s)

in our test we require thin therefore it returns a Thin rack handler and setup a threaded server

  # Starts the server by running the Rack Handler.
  def start_server(handler, server_settings, handler_name)
    handler.run(self, server_settings) do |server|
            ....
            server.threaded = settings.threaded if server.respond_to? :threaded=

$GEM_HOME/gems/thin-1.6.2/lib/thin/server.rb

# Start the server and listen for connections.
def start
  raise ArgumentError, 'app required' unless @app

  log_info  "Thin web server (v#{VERSION::STRING} codename #{VERSION::CODENAME})"
  ...      
  log_info "Listening on #{@backend}, CTRL+C to stop"

  @backend.start { setup_signals if @setup_signals }
end

$GEM_HOME/gems/thin-1.6.2/lib/thin/backends/base.rb

  # Start the backend and connect it.
  def start
    @stopping = false
    starter   = proc do
      connect
      yield if block_given?
      @running = true
    end

    # Allow for early run up of eventmachine.
    if EventMachine.reactor_running?
      starter.call
    else
      @started_reactor = true
      EventMachine.run(&starter)
    end
  end


来源:https://stackoverflow.com/questions/25450769/single-thread-still-handles-concurrency-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!