3

This is my web app:

class Front < Sinatra::Base
  configure do
    set :server, :thin
  end
  get '/' do
    'Hello, world!'
  end 
end

I start it like this:

Front.start!

Works great, but I want to configure Thin to be "threaded". I know it's possible, according to their documentation. But I can't figure out how to pass that threaded: true parameter to Thin. I tried this and it doesn't work:

configure do
  set :server_settings, threaded: true
end
yegor256
  • 102,010
  • 123
  • 446
  • 597
  • Why not use thin.yml? – Sergio Tulentsev Oct 30 '18 at 15:05
  • @SergioTulentsev how exactly? I'm ready to use it, but how do I tell Thin where it's located? – yegor256 Oct 30 '18 at 15:17
  • 1
    Through the command-line: `thin start -C config/thin.yml` – Sergio Tulentsev Oct 30 '18 at 15:18
  • @SergioTulentsev I don't start my Sinatra app from the command line, as you see in the question above. – yegor256 Oct 30 '18 at 15:34
  • 2
    "I don't start my Sinatra app from the command line" - But of course you do, by doing `rackup` or something similar. By the time thin boots your app, it may be already too late to change its architecture. I am actually mildly surprised that sinatra lets you choose the handler in the first place. I shall find out how it's done. – Sergio Tulentsev Oct 30 '18 at 15:36
  • @lacostenycoder yes, there are reasons. I would not ask this question here otherwise. I know how to configure it from command line. My business case is different. – yegor256 Oct 30 '18 at 15:37

1 Answers1

2

The thin web server is threaded by default when started in the way you describe.

# thin_test.rb
require 'sinatra/base'

class Front < Sinatra::Base
  configure do
    set :server, :thin
  end

  get '/' do
    'Hello, world!'
  end 

  get '/foo' do
    sleep 30
    'bar'
  end
end

Front.start!

Start with:

ruby thin_test.rb

Confirm with:

# will hang for 30 seconds while sleeping
curl localhost:4567/foo

# will complete successfully while the other request is pending
curl localhost:4567
Hello, world!

There is additional detail in this answer about how Sinatra uses other web servers.

If this doesn't work for some reason, it may be possible to hack together something with the server_settings option, which is generally only useful for WEBrick unless you use some undocumented ways to force it:

require 'sinatra/base'
require 'thin'

class ThreadedThinBackend < ::Thin::Backends::TcpServer
  def initialize(host, port, options)
    super(host, port)
    @threaded = true
  end
end

class Front < Sinatra::Base
  configure do
    set :server, :thin

    class << settings
      def server_settings
        { :backend => ThreadedThinBackend }
      end
    end
  end

  get '/' do
    'Hello, world!'
  end 

  get '/foo' do
    sleep 30
    'foobar'
  end
end

Front.start!

It's hard for me to tell if this example is the cause of it being threaded though, because it starts in threaded mode by default. That said, it doesn't raise an exception and does run in threaded mode:

# will hang for 30 seconds while sleeping
curl localhost:4567/foo

# will complete successfully while the other request is pending
curl localhost:4567
Hello, world!

More information about server_settings can be found here, here, and here.

anothermh
  • 9,815
  • 3
  • 33
  • 52
  • This example doesn't really work. If you change that `@threaded` to `@maximum_connections = 10` and run again, you will see in the logs that the value is still 1024, which is the default one. – yegor256 Nov 04 '18 at 15:09