This repository has been archived by the owner on Jun 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Supervised TCPServer, Yielding Listeners Easily :: Unmaintained, switch to Unicorn or Rainbows!
License
jeremyevans/ruby-style
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
= style (Supervised TCPServer, Yielding Listeners Easily) style is a Ruby program that provides a supervised TCPServer (or TCPServers) with multiple listening childing processes. It allows the child processes to be killed and respawned while making sure that there are always child processes available to listen to requests. It automatically respawns dead child processes. It allows for increasing and decreasing the number of child processes on the fly. style is distributed as a gem, and can be installed with: sudo gem install ruby-style Feedback/Bugs/Support Requests should be handled through RubyForge at http://rubyforge.org/projects/ruby-style/. The RDoc is available at http://ruby-style.rubyforge.org. Source is available at github: http://github.com/jeremyevans/ruby-style == Highlights * Always has child listeners available, so no connections are lost when listeners are restarted * Automatically restarts dead child processes * Supports both single port and multiple port clustering, with an arbitrary number of listeners per port * Supports increasing and decreasing the number of child processes per port on the fly * Supports both command line and yaml config file configuration * Is easily extensible to support running other frameworks and protocols other than the included ones (Rails; SCGI, Mongrel, Thin, and Evented Mongrel) == Running and configuration To see the available commands and possible and default configuration options, just run the program without any arguments: style [option value, ...] (decrement|halt|increment|restart|run|start|stop) Options: -a, --adapter Adapter/Framework to use [rails] -b, --bind IP address to bind to [127.0.0.1] -c, --config Location of config file [style.yaml] -d, --directory Working directory [.] -D, --debug Run the program in the foreground without forking [No] -f, --fork Number of listners on each port [1] -h, --handler Handler/Server to use [mongrel] -k, --killtime Number of seconds to wait when killing each child [2] -l, --logfile Where to redirect STDOUT and STDERR [style.log] -n, --number Number of ports to which to bind [1] -p, --port Starting port to which to bind [9999] -P, --pidfile Location of pid file [style.pid] -u, --unsupervised Whether to run unsupervised [No] Here's what the various commands do: * decrement (USR2) - Decrease the number of listeners per port by 1 * halt (TERM) - Immediately shutdown the child processes and exit * increment (USR1) - Increase the number of listeners per port by 1 * restart (HUP) - Replace the current listeners with new listeners * run - Runs the supervisor and listening processes without detaching * start - Starts the supervisor process and the listening processes * stop (INT) - Gracefully shutdown the child processes and exit All commands except start and run just send the listed signal to the preexisting supervisor process specified in the pid file. The signals can be sent directly to style when started with the run command, which is the natural way to use style with runit or daemontools. Note that the -d (--directory) option changes the working directory of the process, so the -c, -l, and -P options are relative to that. Here's a longer explanation of the options: -a, --adapter Adapter/Framework to use [rails] This is the adapter/framework to use. Support for Rails is included in the distribution, and is special-cased. Any other value runs require with the argument given. -b, --bind IP address to bind to [127.0.0.1] This is the TCP/IP networking socket to bind to. It defaults to the loopback address because generally the web application runs on the same physical server as the web server. If this is not the case, change it to an externally available IP, and make sure to lock down access to the port via a firewall. -c, --config Location of config file [config/style.yaml] This is the configuration file for style. It is recommended that you use this instead of the command line configuration, as it saves typing. This path is relative to the working directory, so if it is not inside the working directory, make sure you specify an absolute path. This option is not configurable from the configuration file. -d, --directory Working directory [.] This is the working directory of the process. It should generally be the path to the root of the application. Alternatively, you can change to the root of the application before hand and then not use this option. This option is not configurable from the configuration file. -D, --debug Run the program in the foreground without forking [No] This runs the program in the program without forking, aiding in debugging a problematic configuration. -f, --fork Number of listners on each port [1] This enables multiple child processes listening on each port. It is recommended that you use -f instead of -n for multiple listeners, since it simplifies the configuration of the webserver, and can also eliminate the need for a proxy such as pound or pen to handle this for you. It defaults to one process per port. Note that when restarting processes, replacement processes are started before the currently listening processes are killed, so it is possibly to have multiple processes listening on a port even if this is left at one. -h, --handler Handler/Server to use [mongrel] This is the handler/server to use. Support for Mongrel, Evented Mongrel, and SCGI is included in the distribution. Support for other servers is easy to add as long as the servers can be modified to use the socket created by style ($STYLE_SOCKET). -k, --killtime Number of seconds to wait when killing each child [2] This sets the time that style between sending shutdown signals to child process, as well as the time between starting a replacement process and killing an existing process. When restarting, the amount of time spent waiting should be between 2-3 * (killtime * number * fork). -l, --logfile Where to redirect STDOUT and STDERR [log/style.log] This is the location of the log file, relative to the working directory. style itself doesn't output anything after it has detached from the listening terminal, but child listening processes might output to STDOUT or STDERR. -n, --number Number of ports to which to bind [1] This makes style start up multiple sockets, one per port starting with the given port (so port, port+1, port+2, ..., port+n). This makes webserver configuration a little more difficult than with just using -f, and might also require a separate proxy such as pound or pen, so you should try just using -f first. -p, --port Starting port to which to bind [9999] This is the starting (or only) port that style will use. If -n is used, all ports will be greater than this one. -P, --pidfile Location of pid file [log/style.pid] This is the pid file, relative to the working directory. The pid file is necessary, as it is what is used by all commands other than start. If incorrect information is in the pid file, the processes won't be stopped when they should be, and you will probably won't be able to start new processes (because the ports will still be in use). -u, --unsupervised Whether to run unsupervised [No] This starts child processes without using a supervisor process. It is not as reliable or as featureful as the regular supervised mode, but those may not be necessary for smaller sites. In unsupervised mode, only restart, start, and stop are valid commands, child processes aren't automatically restarted when they die, and you may lose connections during restarts. Every one of the long options can also be specified in the config file. Also, the config file must be used if you want to specify any settings specific to adapter being used (such as modifying the Rails environment setting). See below for information on the adapter_config config file variable. == The config file Example Rails+Mongrel style.yaml that listens on ports 8912 and 8193 on any interface, with three listeners per port. Note how the :adapter_config entry is used to set up settings specific to the Rails adapter, such as placing Rails in development mode. Ignore the pipes at the beginning of the line, blame RDoc limitations. | --- | :port: 8912 | :bind: "" | :fork: 3 | :number: 2 | :killtime: 1 | :adapter: rails | :handler: mongrel | :adapter_config: | :environment: development | :log_file: log/rails-mongrel.log | :docroot: public | :num_processors: 99 | :timeout: 100 Example Rails+SCGI style.yaml that has four listeners on port 8912: | --- | :port: 8912 | :fork: 4 | :number: 1 | :adapter: rails | :handler: scgi | :adapter_config: | :logfile: log/railsscgi.log | :maxconns: 10 | :environment: production Configuration for running Rails with Thin on ports 3456-3459 with one listener on each port: | --- | :port: 3456 | :number: 4 | :adapter: rails | :handler: thin Very simple configuration that runs Ramaze (with the default start.rb runner) +Evented Mongrel in unsupervised mode on port 3000. | --- | :port: 3000 | :unsupervised: 1 | :adapter: start | :handler: evented_mongrel Using the generic adapter to host a camping application (you are responsible for having the camping application in a my_camping_app.rb file in your $LOAD_PATH that uses Mongrel to run camping): | --- | :port: 3301 | :adapter: my_camping_app | :environment: | RACK_ENV: production One important thing to note from the example above is that you can specify an :environment key in the config file that should be a hash. If it is provided, the hash under it will be added to the environment before the child processes are loaded. == How restarting works Restarting works by starting a new child process, waiting for killtime, and then killing the exisiting process. It repeats this for all existing child processes. For example: # style idling with three listeners Thu Sep 6 12:01:47 PDT 2007 11460 ?? I 0:00.00 ruby: RailsMongrelStyle dir:/home/billg/testrails supervisor (ruby) 6540 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 272 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 27808 ?? I 0:02.51 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) # Restart occurs, new process started (1207) Thu Sep 6 12:01:49 PDT 2007 11460 ?? I 0:00.00 ruby: RailsMongrelStyle dir:/home/billg/testrails supervisor (ruby) 27808 ?? I 0:02.51 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 272 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 6540 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 1207 ?? R 0:00.95 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) # Old process killed (27808) Thu Sep 6 12:01:51 PDT 2007 11460 ?? I 0:00.01 ruby: RailsMongrelStyle dir:/home/billg/testrails supervisor (ruby) 6540 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 272 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 1207 ?? I 0:02.51 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) # New process started (3204) Thu Sep 6 12:01:53 PDT 2007 11460 ?? I 0:00.01 ruby: RailsMongrelStyle dir:/home/billg/testrails supervisor (ruby) 272 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 6540 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 1207 ?? I 0:02.51 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 3204 ?? R 0:01.01 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) # Old process killed (6540) Thu Sep 6 12:01:55 PDT 2007 11460 ?? I 0:00.01 ruby: RailsMongrelStyle dir:/home/billg/testrails supervisor (ruby) 272 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 1207 ?? I 0:02.51 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 3204 ?? I 0:02.49 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) # New process started (6766) Thu Sep 6 12:01:57 PDT 2007 11460 ?? I 0:00.01 ruby: RailsMongrelStyle dir:/home/billg/testrails supervisor (ruby) 272 ?? I 0:02.52 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 1207 ?? I 0:02.51 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 3204 ?? I 0:02.49 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 6766 ?? R 0:00.99 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) # Old process killed (272) Thu Sep 6 12:01:59 PDT 2007 11460 ?? I 0:00.01 ruby: RailsMongrelStyle dir:/home/billg/testrails supervisor (ruby) 1207 ?? I 0:02.51 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 3204 ?? I 0:02.49 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) 6766 ?? I 0:02.49 ruby: RailsMongrelStyle dir:/home/billg/testrails port:8912 environment:production (ruby) Result, three brand new listening processes, total time to restart is about 12 seconds (2 * (2 killtime * 1 number * 3 fork)). == Other handlers To add support for another handler, make sure the instead of creating a socket, it uses the socket provided by style, available in the global variable $STYLE_SOCKET. See existing handler code to see how Mongrel, SCGI, and Event Machine were modified to support this. Style loads handlers from style/handler relative to the load path, so you can add your own handlers without modifying the program, as long as you place the files somewhere in the load path. == Changes to the default config, logfile, and pidfile in 1.2.0 Previously, style had the following defaults: * config - config/style.yaml * logfile - log/style.log * pidfile - log/style.pid These made sense because style was originally designed to serve Rails applications, which all have config and log directories. Now that style serves more types of applications, and few of those have config or log directories, these no longer made good defaults. The new defaults use the same filename, without the directory: * config - style.yaml * logfile - style.log * pidfile - style.pid == Changes to adapter handling in 1.2.0 Adapter handling was simplified in 1.2.0. Because there is no easy script that loads rails, there is still a rails adapter. However, for all other frameworks you would want to use, just specify the file you want to require as the adapter. This simplifies things and allows you to specify your adapter file on the command line: style -a sinatra_runner start Before, this wasn't possible, you had to set up a configuration file or put the adapter file you wanted to use in a style/adapter subdirectory in the load path. == Upgrading from 1.1.*, previously using ramaze adapter Previously, if you used the following configuration: | --- | :adapter: ramaze You should change it to: | --- | :adapter: start If you specified your own :runner via :adapter_config, just use that runner name for the :adapter instead of start. The Ramaze adapter had some default settings that you might want to consider: :test_connections=>false, :force=>true You should make sure your ramaze runner sets the correct :adapter for Ramaze to use (it should use the same one as style uses). Having it set the :host and :port are good ideas, otherwise it may display those incorrectly. You should make sure your ramaze runner actually calls Ramaze.start, as well. == Upgrading from 1.1.*, previously using generic adapter If you were previously using the generic adapter, the upgrade is simple. Change the following cofiguration from: | --- | :adapter: generic | :adapter_config: | :script: cse To: | --- | :adapter: cse == FAQ Q: Does this run on Windows? A: Only using debug mode (--debug, -D). All other modes use fork, which isn't supported on Windows. Q: Does it work with Capistrano yet? A: I haven't tried. It probably can, but it will take a little custom work.
About
Supervised TCPServer, Yielding Listeners Easily :: Unmaintained, switch to Unicorn or Rainbows!
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published