From 2fabb099a6e47dade5b6cb24d4b943b15c569b0f Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Tue, 16 Jul 2019 15:41:40 -0400 Subject: [PATCH] Improve README + Remove unnecessary words + Clarify some sections --- README.md | 58 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 3bd0c5e6b8..3fa7597cb9 100644 --- a/README.md +++ b/README.md @@ -10,36 +10,38 @@ [![Code Climate](https://codeclimate.com/github/puma/puma.svg)](https://codeclimate.com/github/puma/puma) [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=puma&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=puma&package-manager=bundler&version-scheme=semver) -Puma is a **simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications** in development and production. +Puma is a **simple, fast, multi-threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications**. ## Built For Speed & Concurrency -Under the hood, Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request in a thread from an internal thread pool. Since each request is served in a separate thread, truly concurrent Ruby implementations (JRuby, Rubinius) will use all available CPU cores. +Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request using a thread pool. Each request is served in a separate thread, so truly concurrent Ruby implementations (JRuby, Rubinius) will use all available CPU cores. Puma was designed to be the go-to server for [Rubinius](https://rubini.us), but also works well with JRuby and MRI. -On MRI, there is a Global VM Lock (GVL) that ensures only one thread can run Ruby code at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing blocking IO to be run concurrently. +On MRI, there is a Global VM Lock (GVL) that ensures only one thread can run Ruby code at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing IO waiting to be done in parallel. ## Quick Start ``` $ gem install puma -$ puma +$ puma ``` +Without arguments, puma will look for a rackup (.ru) file in the current working directory called `config.ru`. + ## Frameworks ### Rails -Puma is the default server for Rails, and should already be included in your Gemfile. +Puma is the default server for Rails, included in the generated Gemfile. -Then start your server with the `rails` command: +Start your server with the `rails` command: ``` -$ rails s +$ rails server ``` -Many configuration options are not available when using `rails s`. It is recommended that you use Puma's executable instead: +Many configuration options and Puma features are not available when using `rails server`. It is recommended that you use Puma's executable instead: ``` $ bundle exec puma @@ -53,7 +55,7 @@ You can run your Sinatra application with Puma from the command line like this: $ ruby app.rb -s Puma ``` -Or you can configure your application to always use Puma: +Or you can configure your Sinatra application to always use Puma: ```ruby require 'sinatra' @@ -72,9 +74,9 @@ Puma uses a thread pool. You can set the minimum and maximum number of threads t $ puma -t 8:32 ``` -Puma will automatically scale the number of threads, from the minimum until it caps out at the maximum, based on how much traffic is present. The current default is `0:16`. Feel free to experiment, but be careful not to set the number of maximum threads to a large number, as you may exhaust resources on the system (or hit resource limits). +Puma will automatically scale the number of threads, from the minimum until it caps out at the maximum, based on how much traffic is present. The current default is `0:16`. Feel free to experiment, but be careful not to set the number of maximum threads to a large number, as you may exhaust resources on the system (or cause contention for the Global VM Lock, when using MRI). -Be aware that additionally Puma creates threads on its own for internal purposes (e.g. handling slow clients). So even if you specify -t 1:1, expect around 7 threads created in your application. +Be aware that additionally Puma creates threads on its own for internal purposes (e.g. handling slow clients). So, even if you specify -t 1:1, expect around 7 threads created in your application. ### Clustered mode @@ -84,9 +86,9 @@ Puma also offers "clustered mode". Clustered mode `fork`s workers from a master $ puma -t 8:32 -w 3 ``` -Note that threads are still used in clustered mode, and the `-t` thread flag setting is per worker, so `-w 2 -t 16:16` will spawn 32 threads in total. +Note that threads are still used in clustered mode, and the `-t` thread flag setting is per worker, so `-w 2 -t 16:16` will spawn 32 threads in total, with 16 in each worker process. -In clustered mode, Puma may "preload" your application. This loads all the application code *prior* to forking. Preloading reduces total memory usage of your application via an operating system feature called [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write) (Ruby 2.0+ only). Use the `--preload` flag from the command line: +In clustered mode, Puma can "preload" your application. This loads all the application code *prior* to forking. Preloading reduces total memory usage of your application via an operating system feature called [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write) (Ruby 2.0+ only). Use the `--preload` flag from the command line: ``` $ puma -w 3 --preload @@ -111,8 +113,7 @@ end This code can be used to setup the process before booting the application, allowing you to do some Puma-specific things that you don't want to embed in your application. -For instance, you could fire a log notification that a worker booted or send something to statsd. -This can be called multiple times. +For instance, you could fire a log notification that a worker booted or send something to statsd. This can be called multiple times. If you're preloading your application and using ActiveRecord, it's recommended that you setup your connection pool here: @@ -125,7 +126,7 @@ on_worker_boot do end ``` -On top of that, you can specify a block in your configuration file that will be run before workers are forked: +`before_fork` specifies a block to be run before workers are forked: ```ruby # config/puma.rb @@ -138,13 +139,13 @@ Preloading can’t be used with phased restart, since phased restart kills and r ### Binding TCP / Sockets -In contrast to many other server configs which require multiple flags, Puma simply uses one URI parameter with the `-b` (or `--bind`) flag: +Bind Puma to a socket with the `-b` (or `--bind`) flag: ``` $ puma -b tcp://127.0.0.1:9292 ``` -Want to use UNIX Sockets instead of TCP (which can provide a 5-10% performance boost)? +To use a UNIX Socket instead of TCP: ``` $ puma -b unix:///var/run/puma.sock @@ -157,13 +158,14 @@ $ puma -b 'unix:///var/run/puma.sock?umask=0111' ``` Need a bit of security? Use SSL sockets: + ``` $ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert' ``` #### Controlling SSL Cipher Suites -Need to use or avoid specific SSL cipher suites? Use `ssl_cipher_filter` or `ssl_cipher_list` options. +To use or avoid specific SSL cipher suites, use `ssl_cipher_filter` or `ssl_cipher_list` options. ##### Ruby: @@ -179,7 +181,7 @@ $ puma -b 'ssl://127.0.0.1:9292?keystore=path_to_keystore&keystore-pass=keystore See https://www.openssl.org/docs/man1.0.2/apps/ciphers.html for cipher filter format and full list of cipher suites. -Don't want to use insecure TLSv1.0 ? +Disable TLS v1 with the `no_tlsv1` option: ``` $ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&no_tlsv1=true' @@ -187,13 +189,13 @@ $ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&no_tlsv1=true' ### Control/Status Server -Puma has a built-in status/control app that can be used to query and control Puma itself. +Puma has a built-in status and control app that can be used to query and control Puma. ``` $ puma --control-url tcp://127.0.0.1:9293 --control-token foo ``` -Puma will start the control server on localhost port 9293. All requests to the control server will need to include `token=foo` as a query parameter. This allows for simple authentication. Check out [status.rb](https://github.com/puma/puma/blob/master/lib/puma/app/status.rb) to see what the app has available. +Puma will start the control server on localhost port 9293. All requests to the control server will need to include control token (in this case, `token=foo`) as a query parameter. This allows for simple authentication. Check out [status.rb](https://github.com/puma/puma/blob/master/lib/puma/app/status.rb) to see what the status app has available. You can also interact with the control server via `pumactl`. This command will restart Puma: @@ -205,13 +207,13 @@ To see a list of `pumactl` options, use `pumactl --help`. ### Configuration File -You can also provide a configuration file which Puma will use with the `-C` (or `--config`) flag: +You can also provide a configuration file with the `-C` (or `--config`) flag: ``` $ puma -C /path/to/config ``` -If no configuration file is specified, Puma will look for a configuration file at `config/puma.rb`. If an environment is specified, either via the `-e` and `--environment` flags, or through the `RACK_ENV` environment variable, the default file location will be `config/puma/environment_name.rb`. +If no configuration file is specified, Puma will look for a configuration file at `config/puma.rb`. If an environment is specified, either via the `-e` and `--environment` flags, or through the `RACK_ENV` environment variable, Puma looks for configuration at `config/puma/.rb`. If you want to prevent Puma from looking for a configuration file in those locations, provide a dash as the argument to the `-C` (or `--config`) flag: @@ -236,7 +238,7 @@ Puma responds to several signals. A detailed guide to using UNIX signals with Pu Some platforms do not support all Puma features. * **JRuby**, **Windows**: server sockets are not seamless on restart, they must be closed and reopened. These platforms have no way to pass descriptors into a new process that is exposed to Ruby. Also, cluster mode is not supported due to a lack of fork(2). - * **Windows**: daemon mode is not supported due to a lack of fork(2). + * **Windows**: Cluster mode is not supported due to a lack of fork(2). ## Known Bugs @@ -278,6 +280,12 @@ $ bundle install $ bundle exec rake ``` +To run a single test file, use the `TEST` environment variable: + +```bash +$ TEST=test/test_binder.rb bundle exec rake test +``` + ## License Puma is copyright Evan Phoenix and contributors, licensed under the BSD 3-Clause license. See the included LICENSE file for details.