Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

properly running sinatra with miltithreading support #937

Closed
celesteking opened this issue Oct 23, 2014 · 10 comments
Closed

properly running sinatra with miltithreading support #937

celesteking opened this issue Oct 23, 2014 · 10 comments

Comments

@celesteking
Copy link

I've got a problem. Your docs don't specify on how to run Sinatra properly in 2014.
I'd like it to support multithreading.

Currently, I have:

require 'sinatra'

module LongNamespace
  class App < Sinatra::Application
     .... all that
  end
end

Now, where do I place LongNamespace::App.run! if LongNamespace::App.app_file == $0? I tried placing it at the bottom of file, which led to running the server twice on Ctrl+C.

I've tried a rackup with config.ru:

require './app'
LongNamespace::App.run! port: 1234

This works perfectly (multithread), but outputs on Ctrl+C:

== Sinatra has ended his set (crowd applauds)
.../rack-1.5.2/lib/rack/builder.rb:133:in `to_app': missing run or map statement (RuntimeError)
        from .../config.ru:2:in `block in <main>'
  ....

I tried LongNamespace::App.run if LongNamespace::App.app_file == $0, this doesn't pick up any routes, server is running like an empty one.

And I'm yet to actually start coding.

@rkh
Copy link
Member

rkh commented Oct 23, 2014

Good news: In 2014 Sinatra is run just the way it was in 2013.

Your config.ru should look like this:

require './app'
run LongNamespace::App

It is also not recommended to inherit from Sinatra::Application, inherit from Sinatra::Base instead.

You should also require 'sinatra/base' instead of require 'sinatra', otherwise Sinatra might try to start a server itself, but with Sinatra::Application as app instead of LongNamespace::App. If you do that, you should also be able to use LongNamespace::App.run! (note the exclamation mark) without using a config.ru. The app_file == $0 and be added, but any other condition can be used, too.

I'd generally recommend using a config.ru for any complex application. See the documentation for main points on how things differ.

require 'sinatra/base'

module LongNamespace
  class App < Sinatra::Base
     # ...
     run! if app_file == $0
  end
end

Concerning multithreading, I'd recommend taking a look at the "Is Sinatra multi threaded?" question on StackOverflow.

Please let us know on how we can improve our documentation. Threads aren't really covered at the moment (since Sinatra itself is not really concerned with your concurrency model) in our README, we should probably change that, but then again, your issues seem not to be related to threading.

@rkh rkh closed this as completed Oct 23, 2014
@celesteking
Copy link
Author

Alright, so the basic idea is never use require 'sinatra', but instead require 'sinatra/base' & subclass Sinatra::Base. This means ability to specify options via ruby app.rb -p 12345 and so on is lost.


Good, I managed to get thin working in multi-thread when run via ruby app.rb, but not with rackup.

That stackoverflow question brings zero value to me as it doesn't explain on how to run sinatra via rack while enabling multi-threading. I understand there's a mix of unrelated technologies and software here, but I need to run that together and there should be a document on how to do it.

rackup of config.ru you presented above gives one-thread server.

Thanks!

@rkh
Copy link
Member

rkh commented Oct 24, 2014

You'll have to pass in which server to use when running backup, like
rackup -s puma.

On Thu, Oct 23, 2014 at 9:44 PM, celesteking notifications@github.com
wrote:

Alright, so the basic idea is never use require 'sinatra', but instead require
'sinatra/base' & subclass Sinatra::Base. This means ability to specify

options via ruby app.rb -p 12345 and so on is lost.

Good, I managed to get thin working in multi-thread when run via ruby
app.rb, but not with rackup.

That stackoverflow question brings zero value to me as it doesn't explain
on how to run sinatra via rack while enabling multi-threading. I understand
there's a mix of unrelated technologies and software here, but I need to
run that together and there should be a document on how to do it.

rackup of config.ru you presented above gives one-thread server.

Thanks!


Reply to this email directly or view it on GitHub
#937 (comment).

@celesteking
Copy link
Author

Yes, with rackup -s thin it's running single-threaded, that's the problem.
When started directly with ruby app.rb, it's multi-threaded.

@rkh
Copy link
Member

rkh commented Oct 28, 2014

thin --threaded start should work to run thin in threaded mode. The
default Rack handler for Thin not using threaded mode is a decision of the
Thin project, not the Sinatra project.

On Sat, Oct 25, 2014 at 1:56 PM, celesteking notifications@github.com
wrote:

Yes, with rackup -s thin it's running single-threaded, that's the problem.
When started directly with ruby app.rb, it's multi-threaded.


Reply to this email directly or view it on GitHub
#937 (comment).

@celesteking
Copy link
Author

That indeed helped. thin --threaded start really needs to be mentioned in docs.
Thanks!

@virtualfunction
Copy link

thin shouldn't need to be threaded. It's driven by Event machine so should be able to handle a multiple requests from one thread / process provided your code isn't performing any long blocking operations

@rkh
Copy link
Member

rkh commented Feb 9, 2015

This is not entirely true. Unless you use some mechanism to give back
control to the event loop (say by using the stream helper), you basically
fall back to a single request being handled at a time.

On Mon, Feb 9, 2015 at 2:43 PM, Jason Earl notifications@github.com wrote:

thin shouldn't need to be threaded. It's driven by Event machine so should
be able to handle a multiple requests from one thread / process provided
your code isn't performing any long blocking operations


Reply to this email directly or view it on GitHub
#937 (comment).

@asia653
Copy link

asia653 commented Feb 20, 2015

According to what was mentioned, there are 3 methods of starting sinatra:

  • rackup
  • ruby app.rb
  • handler start (thin start/puma)

Should this be condensed somehow?

@rkh
Copy link
Member

rkh commented Feb 24, 2015

You can also start Sinatra from a custom Ruby script, by invoking Sinatra::Application.run! or Rack::Server.start or similar, but that's probably not relevant for most users.

kgrz added a commit to kgrz/sinatra that referenced this issue Apr 6, 2015
Issue: sinatra#941
Discussion: sinatra#937

Although threading depends on the underlying Rack handler, the absence
of any mention of multi-threaded mode/concurrency seems to confuse users
and it was decided to add some pointers to clarify this.
kgrz added a commit that referenced this issue Sep 11, 2015
Issue: #941
Discussion: #937

Although threading depends on the underlying Rack handler, the absence
of any mention of multi-threaded mode/concurrency seems to confuse users
and it was decided to add some pointers to clarify this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants