Does one thread still handle concurrency request?

The Ruby process is a single thread. When we start one process using a thin server, why can we still handle the 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 this is due to the event-machine framework, then the above code is actually a synchronization code that is not used to use EM.

+3
source share
1 answer

: " IO/ " http://merbist.com/2011/02/22/concurrency-in-ruby-explained/: " , Twisted, EventMachine Node.js. Ruby EventMachine - EventMachine, Thin, EM-/, ".

EventMachine.defer  *   EventMachine.   - , ( "" )   , EventMachine.

, , ( )   EventMachine.   EventMachine , , ( " " )   .

, , . , - .  *

, HTTP- , , process Connecction. $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

.. , EventMachine.defer

, EventMachine : , Sinatra ($GEM_HOME/gems/sinatra-1.4.5/base.rb) Sinatra Thin, Puma, Mongrel WEBrick.

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

detect_rack_handler Rack:: Handler

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

,

  # 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
+2

All Articles