Skip to content

Introduce explicit rails server handler option#32058

Merged
kaspth merged 2 commits into
rails:masterfrom
gsamokovarov:rails-server-x-option
Mar 4, 2018
Merged

Introduce explicit rails server handler option#32058
kaspth merged 2 commits into
rails:masterfrom
gsamokovarov:rails-server-x-option

Conversation

@gsamokovarov

@gsamokovarov gsamokovarov commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

I mistype rails server production instead of rails server -e production expecting to lunch a server in the production environment
all the time. However, the signature of rails server --help is:

Usage:
  rails server [puma, thin etc] [options]

This means that the production argument is being interpreted as a Rack
server handler like Puma, Thin or Unicorn.

Should we argue for the rails server production? I'm not sure of the
reasons, but the rails console production behavior was deprecated in:
#29358, so parity with the existing
rails console production usage may not hold anymore.

In any case, this PR introduces an explicit option for the Rack servers
configuration. I call them --handlers (or -x for short, as -h is
already as the shortcut for --help) to avoid the rails server --server tantrum.

The new interface of rails server is:

Usage:
  rails server [handler] [options]

Options:
  -p, [--port=port]                        # Runs Rails on the specified port - defaults to 3000.
  -b, [--binding=IP]                       # Binds Rails to the specified IP - defaults to 'localhost' in development and '0.0.0.0' in other environments'.
  -c, [--config=file]                      # Uses a custom rackup configuration.
                                           # Default: config.ru
  -d, [--daemon], [--no-daemon]            # Runs server as a Daemon.
  -e, [--environment=name]                 # Specifies the environment to run this server under (development/test/production).
  -x, [--handler=name]                     # Specifies the Rack server to run the application (thin/puma/webrick).
  -P, [--pid=PID]                          # Specifies the PID file.
                                           # Default: tmp/pids/server.pid
  -C, [--dev-caching], [--no-dev-caching]  # Specifies whether to perform caching in development.
      [--early-hints], [--no-early-hints]  # Enables HTTP/2 early hints.

As a bonus, if you mistype the handler, you'll get an auto-correction
message:

$ rails s tin
Could not find handler 'tin'. Maybe you meant 'thin' or 'cgi'?
Run `rails server --help` for more options.

@rails-bot

Copy link
Copy Markdown

r? @schneems

(@rails-bot has picked a reviewer for you, use r? to override)

@gsamokovarov

Copy link
Copy Markdown
Contributor Author

The previous error was:

$ rails server production
Exiting
Traceback (most recent call last):
	36: from bin/rails:3:in `<main>'
	35: from bin/rails:3:in `load'
	34: from /Users/genadi/Development/bithost/dashboard.bithost.io/bin/spring:15:in `<top (required)>'
	33: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:70:in `require'
	32: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:70:in `require'
	31: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `<top (required)>'
	30: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `load'
	29: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/spring-2.0.2/bin/spring:49:in `<top (required)>'
	28: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client.rb:30:in `run'
	27: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/command.rb:7:in `call'
	26: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/rails.rb:28:in `call'
	25: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/rails.rb:28:in `load'
	24: from /Users/genadi/Development/bithost/dashboard.bithost.io/bin/rails:9:in `<top (required)>'
	23: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `require'
	22: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:249:in `load_dependency'
	21: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `block in require'
	20: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/bootsnap-1.1.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
	19: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/bootsnap-1.1.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
	18: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands.rb:18:in `<main>'
	17: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/command.rb:46:in `invoke'
	16: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/command/base.rb:65:in `perform'
	15: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/thor-0.20.0/lib/thor.rb:387:in `dispatch'
	14: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/thor-0.20.0/lib/thor/invocation.rb:126:in `invoke_command'
	13: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/thor-0.20.0/lib/thor/command.rb:27:in `run'
	12: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/server/server_command.rb:142:in `perform'
	11: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/server/server_command.rb:142:in `tap'
	10: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/server/server_command.rb:147:in `block in perform'
	 9: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/server/server_command.rb:47:in `start'
	 8: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/server/server_command.rb:76:in `print_boot_information'
	 7: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/server/server_command.rb:105:in `use_puma?'
	 6: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/rack-2.0.4/lib/rack/server.rb:301:in `server'
	 5: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/rack-2.0.4/lib/rack/handler.rb:16:in `get'
	 4: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/rack-2.0.4/lib/rack/handler.rb:74:in `try_require'
	 3: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `require'
	 2: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:249:in `load_dependency'
	 1: from /Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `block in require'
/Users/genadi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/bootsnap-1.1.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:19:in `require': cannot load such file -- rack/handler/production (LoadError)

@kaspth kaspth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to adding the argument validation. But I don't understand why it follows that we should turn the server positional arg into an option?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're on Ruby 2.3 now, so lets use the squiggly heredoc <<~

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think this might be clearer as:

suggestions = HANDLERS.sort_by { |h| levenshstein_distance(handler, h) }.map(&:inspect)

Don't think the first(2) makes sense since we use first and second below — there's only 8 things in the array, we aren't saving anything with it anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only subtle difference with .map(&:inspect) is that the message contains double quotes instead of single ones.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might prefer %w( … )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know Rack uses handler, but it reads a tad too generic here for me — especially if the shorthand is -x. How about -r for runner? E.g. the thing to run the rails server.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--using? Runner seems particularly problematic given rails runner.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewd yeah, definitely thought that -r is on sketchy ground because of that clash. I like --using. 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--using sounds good to me too.

Comment thread railties/test/commands/server_test.rb Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think attr_reader :output and @output makes sense. We can just do:

assert_match(/Could not find handler 'tink'. Maybe you meant 'thin' or 'cgi'/, run_command(["tink"]))

Then it'll match our test/application/test_runner_test.rb tests too.

Comment thread railties/test/commands/server_test.rb Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How deterministic is it that cgi will be the other option here? I don't think we'd want intermittent test failures here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handlers list is hard-coded, as we don't have a clean way to query the handlers from rack/lib/rack/handler.rb. If the order of the HANDLERS doesn't change often, the test should be stable.

@matthewd

matthewd commented Feb 24, 2018

Copy link
Copy Markdown
Member

@kaspth we removed the positional parameter for console in #29358; I don't see why we'd want to retain it for server but not console.

(Specifically, given that we can only load a handler that's available in the Gemfile, and that we automatically load the first handler that's available in the Gemfile, it seems pretty rare to me for people to have cause to name a handler at all.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICS this could end up suggesting exactly what they typed, which seems not-good. If handler is in HANDLERS, maybe we should instead suggest that they're missing a Gemfile entry.

@kaspth

kaspth commented Feb 24, 2018

Copy link
Copy Markdown
Contributor

@matthewd sure, but that was for the environment, no? I thought bin/rails dbconsole replicant -e production was still possible?

Anyway, you're right that passing it manually is probably a minority case, so lets go with the deprecation — and --using 👍

@gsamokovarov

Copy link
Copy Markdown
Contributor Author

I have changed the option to --using and deprecated the passing of the Rack server as a regular argument.

@kaspth

kaspth commented Feb 25, 2018

Copy link
Copy Markdown
Contributor

This is probably for another time, but… I just realized that now we're on 2.3+ we could leverage the DidYouMean gem's spellchecker: https://github.com/yuki24/did_you_mean/blob/4d4484940cdab27566538e6453ff428d39fbad7a/lib/did_you_mean/spell_checker.rb#L8

unless HANDLERS.include?(options[:using])
  DidYouMean::SpellChecker.new(HANDLERS).correct(options[:using])
end
irb(main):002:0> c = DidYouMean::SpellChecker.new(dictionary: [ 'cgi', 'puma' ])
=> #<DidYouMean::SpellChecker:0x00007fa055866ee0 @dictionary=["cgi", "puma"]>
irb(main):003:0> c.correct('cgy')
=> ["cgi"]
irb(main):004:0> c.correct('pumma')
=> ["puma"]

We could also remove Rails' Levenshtein distance method from other places.

@kaspth kaspth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting real close!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing argv validation seems like it should a concern of the command and not the server itself. Both include Rails::Command::Behavior and rails server --help seem to allude as much.

Could we move it to the command if we do this?

capturing_missing_handler do
  server.start
end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried that as well – it's still messy because levenshtein_distance is a private class method:

        def suggest_rack_server(handler)
          if handler.in?(HANDLERS)
            <<~MSG
              Could not load server "#{handler}". Maybe you need the add it to the Gemfile?

                gem "#{handler}"

              Run `rails server --help` for more options.
            MSG
          else
            suggestions = HANDLERS.sort_by { |h| self.class.send(:levenshtein_distance, handler, h) }.map(&:inspect)

            <<~MSG
              Could not find server "#{handler}". Maybe you meant #{suggestions.first} or #{suggestions.second}?
              Run `rails server --help` for more options.
            MSG
          end
        end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing the stopgap to inlining the HandlerSuggestion module in the command is this unless. But I don't fully understand why we need it? Isn't it fine for the server to say Exiting in the off case that a handler is missing?

@gsamokovarov gsamokovarov Feb 25, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the stopgap is the levenstein_distance method being private and defined in the Rails::Command::Behavior module which carries command specific helpers. Decided to at least isolate it. I'd love to revisit the levenshtein_distance usage or swap it for the algo in DidYouMean, but I'd like to do it in a follow-up change, as it will have to touch the generator commands as well.

The guard here is for my personal aesthetic reasons. 😅 This is the message with the trailing Exiting:

Could not load server "unicorn". Maybe you need the add it to the Gemfile?

  gem "unicorn"

Run `rails server --help` for more options.
Exiting

The Exiting line seems redundant to me, especially with "Run rails server --help for more options." as a final suggestion. Maybe the user mistyped an option and triggered this?

Can an option be to complicate the existing guard a bit and move the missing_handler check there?

    # ...
    ensure
      # The '-h' option calls exit before @options is set.
      # If we call 'options' with it unset, we get double help banners.
      puts "Exiting" unless @options && options[:daemonize] || missing_handler
    end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'd probably extract the message into a method like below, but it's probably fine like this :)

@server = deprecate_positional_using(using) || options[:using]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I think I can extract it in a separate method.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use <<~ here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still needs the squish; deprecation messages should not be hard-wrapped on output.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure to only rescue a LoadError for "rack/handler/#{options[:using]}"; if something else is wrong, the original exception will do a better job of describing the issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rack::Handler.get can raise either LoadError or NameError, if the Puma constant does not exist after the rack/handler/puma require, for example. I think I can override the Rack::Server#server method to isolate the error catch.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can not deal with this by explicitly calling Rack::Handler.get before starting server?
I am also concerned that other errors by LoadError will be wrapped by this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, I'll do the changes accordingly.

@gsamokovarov

Copy link
Copy Markdown
Contributor Author

@kaspth, I think I'll be able to get the printing out of the Rails::Server class and put it into the command. I had a couple of naive attempts but part of the printing needs to know about whether Rails::Server#server is puma and this crosses some boundaries, but I'm sure we can get it.

As for moving the handler suggestion logic entirely into the Rails::Command::ServerCommand it may not be as pretty because of the current Rails::Command::Behavior concern ahem, behavior 😅, that introduces the levenstein_distance method as private class method, which is pretty specific to the first place it was used.

Comment thread railties/CHANGELOG.md Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bin/rails server ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious. Is the user using the server option so much that mistyped check is needed?
I understand that mistakenly specify server as env. But will not it solve the necessity of option to specify server?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@y-yagi doubt it's used often. This tries to give you more context on what actually happens when you pass a positional argument. I'm setting the suggestions here by suggestion (rim-shot). 😅 Anyway, I think it's quite easy to setup the suggestions and we can follow the example in more command options that accept a fixed set of values.

@gsamokovarov

Copy link
Copy Markdown
Contributor Author

Friends, I have moved the printing out of Rails::Server. Want to take another look? There are still some funky bits, but I think we're getting there.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can wrap this in a capturing method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. The purpose of the Exiting message is to show up, for example, when you CTRL-C/terminate a running server.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url can be nil here, if we're not on Puma.

@kaspth kaspth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like where you took this in this round, Genadi! Hadn't thought of extracting all the printing to the command.

Also don't be afraid to say if you've had enough review rounds and would rather focus on wrapping it up. Then we'll find a way to cut it.

I've been using this case to ease back into the command infrastructure and what exactly the responsibility of a command should be. So if it feels like it's playing around a little bit — that's because it is! 😄

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

def serveable? # :nodoc:
  server
  true
rescue LoadError, NameError
  false
end

Then in the command:

unless server.serveable?
  say HandlerSuggestion.message(using) # We ought to use `say` now that we're in the command.
  return
end

Hell, we could even get server.start to yield to a finalizer block when it exits. Then it'd be:

server.start do |exited_successfully|
  if exited_successfully
    say "Exiting" unless options[:daemon]
  else
    say HandlerSuggestion.message(using)
  end
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh. The last suggestion won't work because of print_boot_information. Maybe there's still something useful we can dig out of the suggestion though? 😊

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kasper, I have tried something similar in the last round. I wasn't able to extract all the params out of print_boot_information, because using can be nil, or empty if we coerce it, but that still won't give us a server name to print.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this being private is what stops us from removing this HandlerSuggestion then lets make it public. It's marked as :doc: anyway, so it's already public API.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also a class method, so I'd have to call it through self.class. We go through lots of hoops to use it now, so I'll extract it in a Rails::Command::Spellchecker module as we already blew up the PR a bit. 😅

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this just use using?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> Booting Puma, where using is usually puma. But yeah, we can save this argument pass.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's let the server build this URL in a nodoc'ed served_url, so we can do server.served_url below.

Then we can keep use_puma?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better and clearer to do this than the @_using construct:

super

deprecate_positional_using if @using
@using ||= options[:using]

@log_stdout = 

@gsamokovarov

Copy link
Copy Markdown
Contributor Author

Don't worry Kasper I'm having fun as well. 😀

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could technically be a backward incompatible change, but:

  1. I don't think we should list Rails::Server in the documentation at all.
  2. This change aims Rails 6, so it should be okay.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. We have listed it in the past, so it's technically public API.
  2. Just because it's a major doesn't mean we should just make undue backwards incompatible changes willy-nilly.

I am learning towards the Rails::Server published as public API being a mistake and not being intended. I don't think any of the other Railties command helpers are public.

What does a GitHub search for Rails::Server say? It might corroborate the above 😊

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we find there's no real usage of Rails::Server on GitHub, I'm 👍 on # :nodoc: (but do add the space so it matches the command nodoc 🤓)

@kaspth kaspth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really like how this turned out 👍

Feels right that the command handles the error printing and the server is more focused on its own boot.

Some minor nits left, then I'll merge.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put a newline after this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For another time: I could totally see us enriching Thor's argument/option with a :suggestions to get messages like this for free. E.g.:

class_option :using, aliases: "-u", type: :string, suggestions: RACK_SERVERS,
  desc: "Specifies the Rack server used to run the application (thin/puma/webrick).", banner: :name

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍, dig that we got rid of these comments.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we find there's no real usage of Rails::Server on GitHub, I'm 👍 on # :nodoc: (but do add the space so it matches the command nodoc 🤓)

@kaspth

kaspth commented Mar 3, 2018

Copy link
Copy Markdown
Contributor

Oh, needs a commit squash and rebase too! Normally we'd want 1 commit, but I'll grant you a commit for the spellchecker change first, then one for the server changes after that if you want. 1 commit is fine too 👍

@gsamokovarov gsamokovarov force-pushed the rails-server-x-option branch 2 times, most recently from 245c603 to dd8b60e Compare March 4, 2018 15:06
I mistype `rails server production` instead of `rails server -e
production` expecting to lunch a server in the production environment
all the time. However, the signature of `rails server --help` is:

```
Usage:
  rails server [puma, thin etc] [options]
```

This means that the `production` argument is being interpreted as a Rack
server handler like Puma, Thin or Unicorn.

Should we argue for the `rails server production`? I'm not sure of the
reasons, but the `rails console production` behavior was deprecated in:
rails#29358, so parity with the existing
`rails console production` usage may not hold anymore.

In any case, this PR introduces an explicit option for the Rack servers
configuration. The option is called `--using` (or `-u` for short) to
avoid the `rails server --server` tantrum.

The new interface of `rails server` is:

```
Usage:
  rails server [using] [options]

Options:
  -p, [--port=port]                        # Runs Rails on the specified port - defaults to 3000.
  -b, [--binding=IP]                       # Binds Rails to the specified IP - defaults to 'localhost' in development and '0.0.0.0' in other environments'.
  -c, [--config=file]                      # Uses a custom rackup configuration.
                                           # Default: config.ru
  -d, [--daemon], [--no-daemon]            # Runs server as a Daemon.
  -e, [--environment=name]                 # Specifies the environment to run this server under (development/test/production).
  -u, [--using=name]                       # Specifies the Rack server used to run the application (thin/puma/webrick).
  -P, [--pid=PID]                          # Specifies the PID file.
                                           # Default: tmp/pids/server.pid
  -C, [--dev-caching], [--no-dev-caching]  # Specifies whether to perform caching in development.
      [--early-hints], [--no-early-hints]  # Enables HTTP/2 early hints.
```

As a bonus, if you mistype the server to use, you'll get an
auto-correction message:

```
$ rails s tin
Could not find handler "tin". Maybe you meant "thin" or "cgi"?
Run `rails server --help` for more options.
```
@gsamokovarov gsamokovarov force-pushed the rails-server-x-option branch from dd8b60e to a951729 Compare March 4, 2018 15:53
@gsamokovarov

Copy link
Copy Markdown
Contributor Author

Kasper, I have searched for Rails::Server usage in GitHub, but the two keywords: rails and server yield a lot of uninteresting results for us. See https://help.github.com/articles/searching-code:

You can't use the following wildcard characters as part of your search query: . , : ; / \ ` ' " = * ! ? # $ & + ^ | ~ < > ( ) { } [ ]. The search will simply ignore these symbols.

This means that we cannot match Rails::Server exactly, because of the : character ignore and we can't be exactly sure whether it's used. I left the # :nodoc: only to the serveable? method.

@kaspth kaspth merged commit f4ddbff into rails:master Mar 4, 2018
@kaspth

kaspth commented Mar 4, 2018

Copy link
Copy Markdown
Contributor

Fine with me! Really glad how this turned out 👏

@gsamokovarov

Copy link
Copy Markdown
Contributor Author

Thanks for the review! 🙇‍♂️

@gsamokovarov gsamokovarov deleted the rails-server-x-option branch March 4, 2018 21:33
@kaspth

kaspth commented Jul 7, 2018

Copy link
Copy Markdown
Contributor

Did some work on the server command a0061d2...1d97b8f and realized I forgot to backport this to 5-2-stable 🤭

y-yagi added a commit that referenced this pull request Jan 18, 2019
…mand"

This reverts commit fa791fb.

Reason: `server` argument was deprecated in Rails 6.0. Ref: #32058.
kaspth pushed a commit that referenced this pull request Mar 11, 2019
- Because just passing the server argument to this command is
  deprecated in #32058
@kunal6673

Copy link
Copy Markdown

Recover all my page

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

Successfully merging this pull request may close these issues.

7 participants