Skip to content

Commit

Permalink
Updating documentation and message
Browse files Browse the repository at this point in the history
  • Loading branch information
kigster committed Jan 24, 2021
1 parent 9ebd665 commit cd922e2
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
# rspec failure tracking
.rspec_status
.ruby-version
Gemfile.lock
/Gemfile.lock

83 changes: 0 additions & 83 deletions Gemfile.lock

This file was deleted.

58 changes: 34 additions & 24 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,53 +1,63 @@
= Puma::Daemon
image::https://github.com/kigster/puma-daemon/workflows/Ruby/badge.svg[link=https://github.com/kigster/puma-daemon/actions?query=workflow%3ARuby]
image::https://codecov.io/gh/kigster/puma-daemon/branch/master/graph/badge.svg?token=asxarMSGbz[link=https://codecov.io/gh/kigster/puma-daemon]

:toc:
:toclevels: 4
:sectnums:
:icons: font

image:https://github.com/kigster/puma-daemon/workflows/Ruby/badge.svg[link=https://github.com/kigster/puma-daemon/actions?query=workflow%3ARuby] image:https://codecov.io/gh/kigster/puma-daemon/branch/master/graph/badge.svg?token=asxarMSGbz[link=https://codecov.io/gh/kigster/puma-daemon]

In version 5.0 of the popular Ruby HTTP server https://github.com/puma/puma[Puma] the developers chose to https://github.com/puma/puma/pull/2170/files[drop the daemonization] support from Puma. They did that because the code wasn't actively maintained. Other and perhaps better options now exist (such as `systemd`, etc), not to mention that many people have switched to Kubernetes and Docker, where you generally want to start all servers in the foreground.

In version 5.0 the authors of a popular Ruby web server https://github.com/puma/puma[Puma] chose to https://github.com/puma/puma/pull/2170/files[remove the daemonization] support from Puma, because the code wasn't wall maintained, and because other and perhaps better options exist (such as `systemd`, etc), not to mention many people have switched to Kubernetes and Docker, where you want to start all servers on the foreground.
And yet, on occasion, it was rather useful and straightforward to use the built-in daemonization feature that was cross-platform and is now gone. Some folks are still using this feature and are therefore stuck with Puma version 4, or must wrap Puma either in the `systemd` manifest or `launchctl plist` on Mac OS-X, or a Docker container. Well, **not anymore!**

And yet, something useful and simple got lost — in our humble opinion. Some folks were indeed using the `--daemonize` features, and in Ruby they are so simple to implement due to `Process.daemon(true)` system library.
NOTE: Add this gem to your dependencies, and make a one line change either in your `config/puma.rb` file, or use `pumad` binary to start Puma as per usual, and you can even leave `-d` flags there (they are ignored when started via `pumad`, and Puma always goes to the background when started that way).

One of the nice features of the old daemonization functionality was that it worked across all platforms.

So, if you want to use the latest and greatest Puma 5+, but have it self-daemonize, this gem is for you.

[NOTE]
====
The goal of this gem was to surgically augment Puma's source code to restore daemonization by merely requiring this gem.
== Compatility

We did not restore the daemonization code for JRuby; so at the moment this will work with the MRI distribution, and possibly others that support `Process.daemon(true)`.

We currently run CI suite on Github Actions against

While this was a nice goal, it has not been accomplished in the current version. The internals of Puma are not always written with external augmentation in mind, for example, we couldn't think of a way to add back the `-d` flags to the Option Parsing routine without having to rewrite the entire method: — which is *not a good solution, because if Puma adds new flags in the future, we would have to keep this overridden method constantly updated, and potentially different depending on the version of Puma you are using.
* MRI Ruby 3.0.0
* MRI Ruby 2.7.2
* MRI Ruby 2.6.6
* MRI Ruby 2.5.7

This is why we took instead the approach that requires you — the user — to make a couple of small changes in your Puma configuration to bring daemonization back, or in your scripts change `puma` to `pumad` and everything will just work.
====

== Design Decisions

This gem's goal was to surgically augment Puma's source code to restore daemonization by merely requiring `puma/daemon`. We almost got there, but not quite.

While this was an admirable goal, it has not been accomplished in the current version. The internals of Puma isn't very easy to monkey-patch or augment. For example, we couldn't think of a way to add back the `-d` flags to the Option Parsing method without having to override the entire method: — which is _not a good solution_, because — what if Puma developers add a new flag in the future? We would have to keep this overridden method frequently updated and potentially choose a different version depending on what version of Puma you are using. That sounds like a nightmare.

It is why instead, we took an approach that requires you — the user — to make a couple of small changes in your Puma configuration to bring daemonization back, or in your scripts, change `puma` to `pumad`, and everything should work. If you run into problems, please https://github.com/kigster/puma-daemon/issues/new[submit an issue].

== Installation

Add this line to your application's Gemfile:

[source,ruby]
----
gem 'puma-daemon'
gem 'puma-daemon', require: false
gem 'puma', '~> 5'
----

And then execute:

$ bundle install

Or install it yourself as:

$ gem install puma -N
$ gem install puma-daemon -N

== Usage

There were two main ways you could daemonize Puma in the past:
There were two ways you could daemonize Puma in the past:

1. By specifying `daemonize` or `daemonize(true)` in your config file.
2. Or, by passing a `-d` or `--daemonize` command line flag.

This gem allows you to daemonize using both ways, but with a small change in each case.
This gem allows you to daemonize using both ways, but with a small caveat in each case.

Please note that both ways require you to include this gem in your Gemfile, but you may specify it as `require: false` — it will only activate if you explicitly require it, or use `pumad` executable.

Expand All @@ -67,14 +77,14 @@ threads 2,3
daemonize
----

With this method you can continue using the standard `puma` executable to get it started, and as long remove any `-d` from the command line, or puma will fail with an error.
With this method you can continue using the standard `puma` executable to get it started, but (and this is important) — **you must remove any `-d` or `--daemonize` from the command line**, or Puma v5 and above will fail with an error.

Here is an example of daemonizing via the config file shown above:
Here is an example of daemonizing via the config file shown above, and using the regular `puma` binary:

[source,bash]
----
❯ gem install puma-daemon puma -N
pumad -C config/puma.rb config.ru
puma -C config/puma.rb config.ru
[98795] Puma starting in cluster mode...
[98795] * Puma version: 5.1.1 (ruby 2.7.2-p137) ("At Your Service")
Expand All @@ -85,7 +95,7 @@ Here is an example of daemonizing via the config file shown above:
[98795] * Workers: 3
[98795] * Restarts: (✔) hot (✔) phased
[98795] * Listening on http://0.0.0.0:3001
[98795] * Daemonizing...
[98795] * Puma Daemon: Daemonizing (puma-daemon v0.1.1)...
----

Note that using this method you can decide whether to daemonize or not by passing true or false to the `daemonize` method.
Expand Down Expand Up @@ -114,7 +124,7 @@ If you replace `puma` with `pumad` — you no longer need to pass any aditional
[98795] * Workers: 3
[98795] * Restarts: (✔) hot (✔) phased
[98795] * Listening on http://0.0.0.0:3000
[98795] * Daemonizing...
[98795] * Puma Daemon: Daemonizing (puma-daemon v0.1.1)...
----

As you can see, at the end it says "Daemonizing".
Expand Down
4 changes: 2 additions & 2 deletions lib/puma/daemon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
require 'puma/cli'

require 'puma/daemon/version'
require 'puma/daemon/cli'
require 'puma/daemon/runner'
require 'puma/daemon/dsl'
require 'puma/daemon/configuration'
require 'puma/daemon/cli'
require 'puma/daemon/dsl'

module Puma
module Daemon
Expand Down
4 changes: 3 additions & 1 deletion lib/puma/daemon/runner.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative 'version'

module Puma
module Daemon
module Runner
Expand All @@ -16,7 +18,7 @@ def daemon?
end

def daemonize!
log '* Daemonizing...'
log "* Puma Daemon: Daemonizing (puma-daemon v#{::Puma::Daemon::VERSION})..."
Process.daemon(true)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/puma/daemon/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Puma
module Daemon
VERSION = '0.1.0'
VERSION = '0.1.1'
end
end
6 changes: 4 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
require 'simplecov'
SimpleCov.start

require 'codecov'
SimpleCov.formatter = SimpleCov::Formatter::Codecov
if ENV['CODECOV_TOKEN']
require 'codecov'
SimpleCov.formatter = SimpleCov::Formatter::Codecov
end

require_relative 'support/puma_helpers'
require 'puma/daemon'
Expand Down

0 comments on commit cd922e2

Please sign in to comment.