Hello community,

here is the log from the commit of package rubygem-puma_worker_killer for 
openSUSE:Factory checked in at 2020-10-05 19:32:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-puma_worker_killer (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-puma_worker_killer.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-puma_worker_killer"

Mon Oct  5 19:32:46 2020 rev:5 rq:838067 version:0.3.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/rubygem-puma_worker_killer/rubygem-puma_worker_killer.changes
    2019-08-06 15:10:29.903771197 +0200
+++ 
/work/SRC/openSUSE:Factory/.rubygem-puma_worker_killer.new.4249/rubygem-puma_worker_killer.changes
  2020-10-05 19:32:55.509151026 +0200
@@ -1,0 +2,25 @@
+Fri Sep 25 14:41:04 UTC 2020 - Stephan Kulow <[email protected]>
+
+updated to version 0.3.1
+ see installed CHANGELOG.md
+
+  ## Main
+  
+  ## 0.3.1
+  
+  - Relax puma dependency (#94)
+  
+  ## 0.3.0
+  
+  - Test on recent ruby versions #84
+  - Add option to adjust restart randomizer (#78)
+  
+  ## 0.2.0
+  
+  - Simplify workers memory calculation in PumaMemory‘s `get_total` method #81
+  - Add rubocop in gemspec and CI, with offenses corrected and unnecessary 
cops disabled.
+  - Add `pre_term`-like `rolling_pre_term` config for terminations caused by 
rolling restart (#86)
+  - Fix compatibility with ruby version 2.3.X (#87)
+  
+
+-------------------------------------------------------------------

Old:
----
  puma_worker_killer-0.1.1.gem

New:
----
  puma_worker_killer-0.3.1.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-puma_worker_killer.spec ++++++
--- /var/tmp/diff_new_pack.5bDVg3/_old  2020-10-05 19:32:56.373154670 +0200
+++ /var/tmp/diff_new_pack.5bDVg3/_new  2020-10-05 19:32:56.373154670 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-puma_worker_killer
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-puma_worker_killer
-Version:        0.1.1
+Version:        0.3.1
 Release:        0
 %define mod_name puma_worker_killer
 %define mod_full_name %{mod_name}-%{version}
@@ -32,7 +32,7 @@
 BuildRequires:  %{rubygem gem2rpm}
 BuildRequires:  %{ruby}
 BuildRequires:  ruby-macros >= 5
-Url:            https://github.com/schneems/puma_worker_killer
+URL:            https://github.com/schneems/puma_worker_killer
 Source:         https://rubygems.org/gems/%{mod_full_name}.gem
 Source1:        gem2rpm.yml
 Summary:        If you have a memory leak in your web code puma_worker_killer 
can

++++++ puma_worker_killer-0.1.1.gem -> puma_worker_killer-0.3.1.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.github/workflows/check_changelog.yml 
new/.github/workflows/check_changelog.yml
--- old/.github/workflows/check_changelog.yml   1970-01-01 01:00:00.000000000 
+0100
+++ new/.github/workflows/check_changelog.yml   2020-09-22 20:38:14.000000000 
+0200
@@ -0,0 +1,12 @@
+name: Check Changelog
+
+on: [pull_request]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - name: Check that CHANGELOG is touched
+      run: |
+        cat $GITHUB_EVENT_PATH | jq .pull_request.title |  grep -i 
'\[\(\(changelog skip\)\|\(ci skip\)\)\]' ||  git diff remotes/origin/${{ 
github.base_ref }} --name-only | grep CHANGELOG.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.rubocop.yml new/.rubocop.yml
--- old/.rubocop.yml    1970-01-01 01:00:00.000000000 +0100
+++ new/.rubocop.yml    2020-09-22 20:38:14.000000000 +0200
@@ -0,0 +1,22 @@
+inherit_from: .rubocop_todo.yml
+
+Naming/AccessorMethodName:
+  Enabled: false
+
+Style/Documentation:
+  Enabled: false
+
+Style/HashSyntax:
+  Enabled: false
+
+Style/ModuleFunction:
+  Enabled: false
+
+Style/StringLiterals:
+  EnforcedStyle: single_quotes
+
+Style/StringLiteralsInInterpolation:
+  EnforcedStyle: double_quotes
+
+Gemspec/RequiredRubyVersion:
+  Enabled: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.rubocop_todo.yml new/.rubocop_todo.yml
--- old/.rubocop_todo.yml       1970-01-01 01:00:00.000000000 +0100
+++ new/.rubocop_todo.yml       2020-09-22 20:38:14.000000000 +0200
@@ -0,0 +1,24 @@
+# This configuration was generated by
+# `rubocop --auto-gen-config`
+# on 2020-04-03 13:12:53 +0200 using RuboCop version 0.81.0.
+# The point is for the user to remove these configuration records
+# one by one as the offenses are removed from the code base.
+# Note that changes in the inspected code, or installation of new
+# versions of RuboCop, may require this file to be generated again.
+
+# Offense count: 1
+# Configuration parameters: IgnoredMethods.
+Metrics/AbcSize:
+  Max: 21
+
+# Offense count: 1
+# Configuration parameters: CountComments, ExcludedMethods.
+Metrics/MethodLength:
+  Max: 11
+
+# Offense count: 32
+# Cop supports --auto-correct.
+# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, 
IgnoreCopDirectives, IgnoredPatterns.
+# URISchemes: http, https
+Layout/LineLength:
+  Max: 252
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.travis.yml new/.travis.yml
--- old/.travis.yml     2019-06-26 21:06:55.000000000 +0200
+++ new/.travis.yml     2020-09-22 20:38:14.000000000 +0200
@@ -1,12 +1,10 @@
 language: ruby
 rvm:
-  - 1.9.3
-  - 2.0.0
-  - 2.1.10
-  - 2.2.9
-  - 2.3.6
-  - 2.4.3
-  - 2.5.0
+  - 2.3.8
+  - 2.4.10
+  - 2.5.8
+  - 2.6.6
+  - 2.7.1
   - ruby-head
   - rbx
 before_install:
@@ -16,3 +14,10 @@
   allow_failures:
     - rvm: ruby-head
     - rvm: rbx
+
+install:
+  - bundle install
+
+script:
+  - bundle exec rubocop
+  - bundle exec rake test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md    2019-06-26 21:06:55.000000000 +0200
+++ new/CHANGELOG.md    2020-09-22 20:38:14.000000000 +0200
@@ -1,3 +1,21 @@
+## Main
+
+## 0.3.1
+
+- Relax puma dependency (#94)
+
+## 0.3.0
+
+- Test on recent ruby versions #84
+- Add option to adjust restart randomizer (#78)
+
+## 0.2.0
+
+- Simplify workers memory calculation in PumaMemory‘s `get_total` method #81
+- Add rubocop in gemspec and CI, with offenses corrected and unnecessary cops 
disabled.
+- Add `pre_term`-like `rolling_pre_term` config for terminations caused by 
rolling restart (#86)
+- Fix compatibility with ruby version 2.3.X (#87)
+
 ## 0.1.1
 
 - Allow PWK to be used with Puma 4 (#72)
@@ -25,3 +43,4 @@
 ## 0.0.3
 
 - Fix memory metrics in on linux
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 2019-06-26 21:06:55.000000000 +0200
+++ new/Gemfile 2020-09-22 20:38:14.000000000 +0200
@@ -1,3 +1,7 @@
-source "https://rubygems.org";
+# frozen_string_literal: true
+
+source 'https://rubygems.org'
 
 gemspec
+
+gem 'rubocop', require: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2019-06-26 21:06:55.000000000 +0200
+++ new/README.md       2020-09-22 20:38:14.000000000 +0200
@@ -3,6 +3,22 @@
 [![Build 
Status](https://travis-ci.org/schneems/puma_worker_killer.png?branch=master)](https://travis-ci.org/schneems/puma_worker_killer)
 [![Help Contribute to Open 
Source](https://www.codetriage.com/schneems/puma_worker_killer/badges/users.svg)](https://www.codetriage.com/schneems/puma_worker_killer)
 
+## !!!!!!!!!!!!!!!! STOP !!!!!!!!!!!!!!!!
+
+Before you use this gem, know that it is dangerous. If you have a memory 
issue, you need to fix the issue. The original idea behind this gem is that it 
would act as a temporary band-aid to buy you time to allow you to fix your 
issues. If you turn this on and don't fix the underlying memory problems, then 
things will only get worse over time.
+
+This gem can also make your performance WORSE. When a worker is killed, and 
comes back it takes CPU cycles and time. If you are frequently restarting your 
workers then you're killing your performance.
+
+Here are some places to start improving your understanding of memory behvior 
in Ruby:
+
+- [Complete Guide to Rails Performance (Book)](https://www.railsspeed.com)
+- [How Ruby uses Memory](https://www.sitepoint.com/ruby-uses-memory/)
+- [Ruby Memory Use (Heroku Devcenter article I 
maintain)](https://devcenter.heroku.com/articles/ruby-memory-use)
+- [Jumping off the Ruby Memory 
Cliff](https://www.schneems.com/2017/04/12/jumping-off-the-memory-cliff/)
+- [How Ruby uses memory 
(Talk)](https://www.schneems.com/2015/05/11/how-ruby-uses-memory.html) (you can 
skip the first story in the video, the rest are about memory)
+- [Debugging a memory leak on 
Heroku](https://blog.codeship.com/debugging-a-memory-leak-on-heroku/)
+
+If you still need this gem, proceed with caution.
 
 ## What
 
@@ -23,14 +39,7 @@
 
 Then run `$ bundle install`
 
-<!--
-## Use
-
-> If you like `puma_worker_killer` consider using [puma_auto_tune 
instead](https://github.com/schneems/puma_auto_tune). It handles memory leaks 
and tunes your workers too!
-
--->
-
-## Turn on Rolling Restarts
+## Turn on Rolling Restarts - Heroku Mode
 
 A rolling restart will kill each of your workers on a rolling basis. You set 
the frequency which it conducts the restart. This is a simple way to keep 
memory down as Ruby web programs generally increase memory usage over time. If 
you're using Heroku [it is difficult to measure RAM from inside of a container 
accurately](https://github.com/schneems/get_process_mem/issues/7), so it is 
recommended to use this feature or use a [log-drain-based worker 
killer](https://github.com/arches/whacamole). You can enable roling restarts by 
running:
 
@@ -55,7 +64,7 @@
 
 ## Enable Worker Killing
 
-If you're not running on a containerized platform you can try to detect the 
amount of memory you're using and only kill Puma workers when you're over that 
limit. It may allow you to go for longer periods of time without killing a 
worker however it is more error prone than rolling restarts. To enable 
measurement based worker killing put this in your `config/puma.rb`:
+If you're not running on a containerized platform (like Heroku or Docker) you 
can try to detect the amount of memory you're using and only kill Puma workers 
when you're over that limit. It may allow you to go for longer periods of time 
without killing a worker however it is more error prone than rolling restarts. 
To enable measurement based worker killing put this in your `config/puma.rb`:
 
 ```ruby
 # config/puma.rb
@@ -108,6 +117,7 @@
   # PumaWorkerKiller: Consuming 54.34765625 mb with master and 2 workers.
 
   config.pre_term = -> (worker) { puts "Worker #{worker.inspect} being killed" 
}
+  config.rolling_pre_term = -> (worker) { puts "Worker #{worker.inspect} being 
killed by rolling restart" }
 end
 PumaWorkerKiller.start
 ```
@@ -130,6 +140,17 @@
 
 However you may want to collect more data, such as sending an event to an 
error collection service like rollbar or airbrake. The `pre_term` lambda gets 
called before any worker is killed by PWK for any reason.
 
+### rolling_pre_term
+
+`config.rolling_pre_term` will be called just prior to worker termination by 
rolling restart when rolling restart is enabled.
+
+It is similar to `config.pre_term`.
+
+Difference:
+
+- `config.pre_term` is triggered only by terminations related with exceeding 
RAM
+- `config.rolling_pre_term` is triggered only by terminations caused by 
enabled rolling restart
+
 ### on_calculation
 
 `config.on_calculation` will be called every time Puma Worker Killer 
calculates memory usage (`config.frequency`). This may be useful for monitoring 
your total puma application memory usage, which can be contrasted with other 
application monitoring solutions.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile        2019-06-26 21:06:55.000000000 +0200
+++ new/Rakefile        2020-09-22 20:38:14.000000000 +0200
@@ -1,4 +1,4 @@
-# encoding: UTF-8
+# frozen_string_literal: true
 
 require 'bundler/gem_tasks'
 
@@ -7,7 +7,7 @@
 
 task :default => [:test]
 
-test_task = Rake::TestTask.new(:test) do |t|
+Rake::TestTask.new(:test) do |t|
   t.libs << 'lib'
   t.libs << 'test'
   t.pattern = 'test/**/*_test.rb'
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma_worker_killer/auto_reap.rb 
new/lib/puma_worker_killer/auto_reap.rb
--- old/lib/puma_worker_killer/auto_reap.rb     2019-06-26 21:06:55.000000000 
+0200
+++ new/lib/puma_worker_killer/auto_reap.rb     2020-09-22 20:38:14.000000000 
+0200
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module PumaWorkerKiller
   class AutoReap
     def initialize(timeout, reaper = Reaper.new)
@@ -16,6 +18,5 @@
         end
       end
     end
-
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma_worker_killer/puma_memory.rb 
new/lib/puma_worker_killer/puma_memory.rb
--- old/lib/puma_worker_killer/puma_memory.rb   2019-06-26 21:06:55.000000000 
+0200
+++ new/lib/puma_worker_killer/puma_memory.rb   2020-09-22 20:38:14.000000000 
+0200
@@ -1,12 +1,13 @@
+# frozen_string_literal: true
+
 module PumaWorkerKiller
   class PumaMemory
     def initialize(master = nil)
       @master  = master || get_master
+      @workers = nil
     end
 
-    def master
-      @master
-    end
+    attr_reader :master
 
     def size
       workers.size
@@ -18,8 +19,6 @@
 
     def term_largest_worker
       largest_worker.term
-    #   Process.wait(largest_worker.pid)
-    # rescue Errno::ECHILD
     end
 
     def workers_stopped?
@@ -31,7 +30,7 @@
     end
 
     def smallest_worker
-      smallest, _ = workers.to_a.first
+      smallest, = workers.to_a.first
       smallest
     end
 
@@ -41,7 +40,7 @@
     end
 
     def largest_worker
-      largest_worker, _ = workers.to_a.last
+      largest_worker, = workers.to_a.last
       largest_worker
     end
 
@@ -53,10 +52,10 @@
     # Will refresh @workers
     def get_total(workers = set_workers)
       master_memory = GetProcessMem.new(Process.pid).mb
-      worker_memory = workers.map {|_, mem| mem }.inject(&:+) || 0
+      worker_memory = workers.values.inject(:+) || 0
       worker_memory + master_memory
     end
-    alias :get_total_memory :get_total
+    alias get_total_memory get_total
 
     def workers
       @workers || set_workers
@@ -72,11 +71,11 @@
     # sorted by memory ascending (smallest first, largest last)
     def set_workers
       workers = {}
-      @master.instance_variable_get("@workers").each do |worker|
+      @master.instance_variable_get('@workers').each do |worker|
         workers[worker] = GetProcessMem.new(worker.pid).mb
       end
       if workers.any?
-        @workers = Hash[ workers.sort_by {|_, mem| mem } ]
+        @workers = Hash[workers.sort_by { |_, mem| mem }]
       else
         {}
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma_worker_killer/reaper.rb 
new/lib/puma_worker_killer/reaper.rb
--- old/lib/puma_worker_killer/reaper.rb        2019-06-26 21:06:55.000000000 
+0200
+++ new/lib/puma_worker_killer/reaper.rb        2020-09-22 20:38:14.000000000 
+0200
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module PumaWorkerKiller
   class Reaper
     def initialize(max_ram, master = nil, reaper_status_logs = true, pre_term 
= nil, on_calculation = nil)
@@ -15,8 +17,9 @@
 
     def reap
       return false if @cluster.workers_stopped?
+
       total = get_total_memory
-      @on_calculation.call(total) unless @on_calculation.nil?
+      @on_calculation&.call(total)
 
       if total > @max_ram
         @cluster.master.log "PumaWorkerKiller: Out of memory. 
#{@cluster.workers.count} workers consuming total: #{total} mb out of max: 
#{@max_ram} mb. Sending TERM to pid #{@cluster.largest_worker.pid} consuming 
#{@cluster.largest_worker_memory} mb."
@@ -29,7 +32,7 @@
         #   A new request comes in, Worker B takes it, and consumes 101 mb 
memory
         #   term_largest_worker (previously here) gets called and terms Worker 
B (thus not passing the about-to-be-terminated worker to `@pre_term`)
         largest_worker = @cluster.largest_worker
-        @pre_term.call(largest_worker) unless @pre_term.nil?
+        @pre_term&.call(largest_worker)
         @cluster.term_worker(largest_worker)
 
       elsif @reaper_status_logs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma_worker_killer/rolling_restart.rb 
new/lib/puma_worker_killer/rolling_restart.rb
--- old/lib/puma_worker_killer/rolling_restart.rb       2019-06-26 
21:06:55.000000000 +0200
+++ new/lib/puma_worker_killer/rolling_restart.rb       2020-09-22 
20:38:14.000000000 +0200
@@ -1,7 +1,10 @@
+# frozen_string_literal: true
+
 module PumaWorkerKiller
   class RollingRestart
-    def initialize(master = nil)
+    def initialize(master = nil, rolling_pre_term = nil)
       @cluster = PumaWorkerKiller::PumaMemory.new(master)
+      @rolling_pre_term = rolling_pre_term
     end
 
     # used for tes
@@ -9,12 +12,17 @@
       @cluster.get_total_memory
     end
 
-    def reap(wait_between_worker_kill = 60) # seconds
+    def reap(seconds_between_worker_kill = 60)
+      # this will implicitly call set_workers
+      total_memory = get_total_memory
       return false unless @cluster.running?
-      @cluster.workers.each do |worker, ram|
-        @cluster.master.log "PumaWorkerKiller: Rolling Restart. 
#{@cluster.workers.count} workers consuming total: #{ get_total_memory } mb. 
Sending TERM to pid #{worker.pid}."
+
+      @cluster.workers.each do |worker, _ram|
+        @cluster.master.log "PumaWorkerKiller: Rolling Restart. 
#{@cluster.workers.count} workers consuming total: #{total_memory} mb. Sending 
TERM to pid #{worker.pid}."
+        @rolling_pre_term&.call(worker)
+
         worker.term
-        sleep wait_between_worker_kill
+        sleep seconds_between_worker_kill
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma_worker_killer/version.rb 
new/lib/puma_worker_killer/version.rb
--- old/lib/puma_worker_killer/version.rb       2019-06-26 21:06:55.000000000 
+0200
+++ new/lib/puma_worker_killer/version.rb       2020-09-22 20:38:14.000000000 
+0200
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module PumaWorkerKiller
-  VERSION = "0.1.1"
+  VERSION = '0.3.1'
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma_worker_killer.rb 
new/lib/puma_worker_killer.rb
--- old/lib/puma_worker_killer.rb       2019-06-26 21:06:55.000000000 +0200
+++ new/lib/puma_worker_killer.rb       2020-09-22 20:38:14.000000000 +0200
@@ -1,22 +1,29 @@
+# frozen_string_literal: true
+
 require 'get_process_mem'
 
 module PumaWorkerKiller
   extend self
 
-  attr_accessor :ram, :frequency, :percent_usage, :rolling_restart_frequency, 
:reaper_status_logs, :pre_term, :on_calculation
+  attr_accessor :ram, :frequency, :percent_usage, :rolling_restart_frequency,
+                :rolling_restart_splay_seconds,
+                :reaper_status_logs, :pre_term, :rolling_pre_term, 
:on_calculation
+
   self.ram           = 512  # mb
   self.frequency     = 10   # seconds
   self.percent_usage = 0.99 # percent of RAM to use
   self.rolling_restart_frequency = 6 * 3600 # 6 hours in seconds
+  self.rolling_restart_splay_seconds = 0.0..300.0 # 0 to 5 minutes in seconds
   self.reaper_status_logs = true
   self.pre_term = nil
+  self.rolling_pre_term = nil
   self.on_calculation = nil
 
   def config
     yield self
   end
 
-  def reaper(ram = self.ram, percent = self.percent_usage, reaper_status_logs 
= self.reaper_status_logs, pre_term = self.pre_term, on_calculation = 
self.on_calculation)
+  def reaper(ram = self.ram, percent_usage = self.percent_usage, 
reaper_status_logs = self.reaper_status_logs, pre_term = self.pre_term, 
on_calculation = self.on_calculation)
     Reaper.new(ram * percent_usage, nil, reaper_status_logs, pre_term, 
on_calculation)
   end
 
@@ -25,9 +32,11 @@
     enable_rolling_restart(rolling_restart_frequency) if 
rolling_restart_frequency
   end
 
-  def enable_rolling_restart(frequency = self.rolling_restart_frequency)
-    frequency = frequency + rand(0..10.0) # so all workers don't restart at 
the exact same time across multiple machines
-    AutoReap.new(frequency, RollingRestart.new).start
+  def enable_rolling_restart(frequency = rolling_restart_frequency,
+                             splay_seconds = rolling_restart_splay_seconds)
+    # Randomize so all workers don't restart at the exact same time across 
multiple machines.
+    frequency += rand(splay_seconds)
+    AutoReap.new(frequency, RollingRestart.new(nil, rolling_pre_term)).start
   end
 end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2019-06-26 21:06:55.000000000 +0200
+++ new/metadata        2020-09-22 20:38:14.000000000 +0200
@@ -1,36 +1,16 @@
 --- !ruby/object:Gem::Specification
 name: puma_worker_killer
 version: !ruby/object:Gem::Version
-  version: 0.1.1
+  version: 0.3.1
 platform: ruby
 authors:
 - Richard Schneeman
-autorequire: 
+autorequire:
 bindir: bin
 cert_chain: []
-date: 2019-06-26 00:00:00.000000000 Z
+date: 2020-09-22 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
-  name: puma
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - ">="
-      - !ruby/object:Gem::Version
-        version: '2.7'
-    - - "<"
-      - !ruby/object:Gem::Version
-        version: '5'
-  type: :runtime
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - ">="
-      - !ruby/object:Gem::Version
-        version: '2.7'
-    - - "<"
-      - !ruby/object:Gem::Version
-        version: '5'
-- !ruby/object:Gem::Dependency
   name: get_process_mem
   requirement: !ruby/object:Gem::Requirement
     requirements:
@@ -45,47 +25,47 @@
       - !ruby/object:Gem::Version
         version: '0.2'
 - !ruby/object:Gem::Dependency
-  name: rack
+  name: puma
   requirement: !ruby/object:Gem::Requirement
     requirements:
-    - - "~>"
+    - - ">="
       - !ruby/object:Gem::Version
-        version: '1.6'
-  type: :development
+        version: '2.7'
+  type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
-    - - "~>"
+    - - ">="
       - !ruby/object:Gem::Version
-        version: '1.6'
+        version: '2.7'
 - !ruby/object:Gem::Dependency
-  name: wait_for_it
+  name: rack
   requirement: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '0.1'
+        version: '2.0'
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '0.1'
+        version: '2.0'
 - !ruby/object:Gem::Dependency
   name: rake
   requirement: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '10.1'
+        version: '13.0'
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '10.1'
+        version: '13.0'
 - !ruby/object:Gem::Dependency
   name: test-unit
   requirement: !ruby/object:Gem::Requirement
@@ -100,6 +80,20 @@
     - - ">="
       - !ruby/object:Gem::Version
         version: '0'
+- !ruby/object:Gem::Dependency
+  name: wait_for_it
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '0.1'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '0.1'
 description: " Kills pumas, the code kind "
 email:
 - [email protected]
@@ -107,7 +101,10 @@
 extensions: []
 extra_rdoc_files: []
 files:
+- ".github/workflows/check_changelog.yml"
 - ".gitignore"
+- ".rubocop.yml"
+- ".rubocop_todo.yml"
 - ".travis.yml"
 - CHANGELOG.md
 - Gemfile
@@ -126,6 +123,7 @@
 - test/fixtures/fixture_helper.rb
 - test/fixtures/on_calculation.ru
 - test/fixtures/pre_term.ru
+- test/fixtures/rolling_pre_term.ru
 - test/fixtures/rolling_restart.ru
 - test/puma_worker_killer_test.rb
 - test/test_helper.rb
@@ -133,7 +131,7 @@
 licenses:
 - MIT
 metadata: {}
-post_install_message: 
+post_install_message:
 rdoc_options: []
 require_paths:
 - lib
@@ -148,8 +146,8 @@
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubygems_version: 3.0.3
-signing_key: 
+rubygems_version: 3.1.2
+signing_key:
 specification_version: 4
 summary: If you have a memory leak in your web code puma_worker_killer can 
keep it
   in check.
@@ -160,6 +158,7 @@
 - test/fixtures/fixture_helper.rb
 - test/fixtures/on_calculation.ru
 - test/fixtures/pre_term.ru
+- test/fixtures/rolling_pre_term.ru
 - test/fixtures/rolling_restart.ru
 - test/puma_worker_killer_test.rb
 - test/test_helper.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/puma_worker_killer.gemspec 
new/puma_worker_killer.gemspec
--- old/puma_worker_killer.gemspec      2019-06-26 21:06:55.000000000 +0200
+++ new/puma_worker_killer.gemspec      2020-09-22 20:38:14.000000000 +0200
@@ -1,28 +1,28 @@
-# -*- encoding: utf-8 -*-
-lib = File.expand_path('../lib', __FILE__)
+# frozen_string_literal: true
+
+lib = File.expand_path('lib', __dir__)
 $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
 require 'puma_worker_killer/version'
 
 Gem::Specification.new do |gem|
-  gem.name          = "puma_worker_killer"
+  gem.name          = 'puma_worker_killer'
   gem.version       = PumaWorkerKiller::VERSION
-  gem.authors       = ["Richard Schneeman"]
-  gem.email         = ["[email protected]"]
-  gem.description   = %q{ Kills pumas, the code kind }
-  gem.summary       = %q{ If you have a memory leak in your web code 
puma_worker_killer can keep it in check. }
-  gem.homepage      = "https://github.com/schneems/puma_worker_killer";
-  gem.license       = "MIT"
+  gem.authors       = ['Richard Schneeman']
+  gem.email         = ['[email protected]']
+  gem.description   = ' Kills pumas, the code kind '
+  gem.summary       = ' If you have a memory leak in your web code 
puma_worker_killer can keep it in check. '
+  gem.homepage      = 'https://github.com/schneems/puma_worker_killer'
+  gem.license       = 'MIT'
 
-  gem.files         = `git ls-files`.split($/)
-  gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
+  gem.files         = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
+  gem.executables   = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
   gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
-  gem.require_paths = ["lib"]
-
-  gem.add_dependency "puma",              ">= 2.7", "< 5"
-  gem.add_dependency "get_process_mem",   "~>  0.2"
-  gem.add_development_dependency "rack", "~> 1.6"
-  gem.add_development_dependency "wait_for_it", "~> 0.1"
-  gem.add_development_dependency "rake",  "~> 10.1"
-  gem.add_development_dependency "test-unit",  ">= 0"
+  gem.require_paths = ['lib']
 
+  gem.add_dependency 'get_process_mem',   '~>  0.2'
+  gem.add_dependency 'puma',              '>= 2.7'
+  gem.add_development_dependency 'rack', '~> 2.0'
+  gem.add_development_dependency 'rake', '~> 13.0'
+  gem.add_development_dependency 'test-unit', '>= 0'
+  gem.add_development_dependency 'wait_for_it', '~> 0.1'
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/big.ru new/test/fixtures/big.ru
--- old/test/fixtures/big.ru    2019-06-26 21:06:55.000000000 +0200
+++ new/test/fixtures/big.ru    2020-09-22 20:38:14.000000000 +0200
@@ -1,4 +1,6 @@
-load File.expand_path("../fixture_helper.rb", __FILE__)
+# frozen_string_literal: true
+
+load File.expand_path('fixture_helper.rb', __dir__)
 
 PumaWorkerKiller.start
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/config/puma_worker_killer_start.rb 
new/test/fixtures/config/puma_worker_killer_start.rb
--- old/test/fixtures/config/puma_worker_killer_start.rb        2019-06-26 
21:06:55.000000000 +0200
+++ new/test/fixtures/config/puma_worker_killer_start.rb        2020-09-22 
20:38:14.000000000 +0200
@@ -1,4 +1,6 @@
-load File.expand_path("../../fixture_helper.rb", __FILE__)
+# frozen_string_literal: true
+
+load File.expand_path('../fixture_helper.rb', __dir__)
 
 before_fork do
   require 'puma_worker_killer'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/default.ru new/test/fixtures/default.ru
--- old/test/fixtures/default.ru        2019-06-26 21:06:55.000000000 +0200
+++ new/test/fixtures/default.ru        2020-09-22 20:38:14.000000000 +0200
@@ -1,4 +1,6 @@
-load File.expand_path("../fixture_helper.rb", __FILE__)
+# frozen_string_literal: true
+
+load File.expand_path('fixture_helper.rb', __dir__)
 
 PumaWorkerKiller.start
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/fixture_helper.rb 
new/test/fixtures/fixture_helper.rb
--- old/test/fixtures/fixture_helper.rb 2019-06-26 21:06:55.000000000 +0200
+++ new/test/fixtures/fixture_helper.rb 2020-09-22 20:38:14.000000000 +0200
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'securerandom'
 
 require 'rack'
@@ -10,10 +12,10 @@
   config.frequency = Integer(ENV['PUMA_FREQUENCY']) if ENV['PUMA_FREQUENCY']
 end
 
-puts "Frequency: #{ PumaWorkerKiller.frequency }" if ENV['PUMA_FREQUENCY']
+puts "Frequency: #{PumaWorkerKiller.frequency}" if ENV['PUMA_FREQUENCY']
 
 class HelloWorld
-  def response(env)
+  def response(_env)
     [200, {}, ['Hello World']]
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/on_calculation.ru 
new/test/fixtures/on_calculation.ru
--- old/test/fixtures/on_calculation.ru 2019-06-26 21:06:55.000000000 +0200
+++ new/test/fixtures/on_calculation.ru 2020-09-22 20:38:14.000000000 +0200
@@ -1,7 +1,9 @@
-load File.expand_path("../fixture_helper.rb", __FILE__)
+# frozen_string_literal: true
+
+load File.expand_path('fixture_helper.rb', __dir__)
 
 PumaWorkerKiller.config do |config|
-  config.on_calculation = lambda { |usage| puts("Current memory footprint: 
#{usage} mb") }
+  config.on_calculation = ->(usage) { puts("Current memory footprint: #{usage} 
mb") }
 end
 PumaWorkerKiller.start
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/pre_term.ru 
new/test/fixtures/pre_term.ru
--- old/test/fixtures/pre_term.ru       2019-06-26 21:06:55.000000000 +0200
+++ new/test/fixtures/pre_term.ru       2020-09-22 20:38:14.000000000 +0200
@@ -1,7 +1,9 @@
-load File.expand_path("../fixture_helper.rb", __FILE__)
+# frozen_string_literal: true
+
+load File.expand_path('fixture_helper.rb', __dir__)
 
 PumaWorkerKiller.config do |config|
-  config.pre_term = lambda { |worker| puts("About to terminate worker: 
#{worker.inspect}") }
+  config.pre_term = ->(worker) { puts("About to terminate worker: 
#{worker.inspect}") }
 end
 PumaWorkerKiller.start
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/rolling_pre_term.ru 
new/test/fixtures/rolling_pre_term.ru
--- old/test/fixtures/rolling_pre_term.ru       1970-01-01 01:00:00.000000000 
+0100
+++ new/test/fixtures/rolling_pre_term.ru       2020-09-22 20:38:14.000000000 
+0200
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+load File.expand_path('fixture_helper.rb', __dir__)
+
+PumaWorkerKiller.config do |config|
+  config.rolling_pre_term = ->(worker) { puts("About to terminate (rolling) 
worker: #{worker.pid}") }
+end
+PumaWorkerKiller.enable_rolling_restart(1, 0..5.0) # 1 second, short 1-5s 
splay.
+
+run HelloWorldApp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/fixtures/rolling_restart.ru 
new/test/fixtures/rolling_restart.ru
--- old/test/fixtures/rolling_restart.ru        2019-06-26 21:06:55.000000000 
+0200
+++ new/test/fixtures/rolling_restart.ru        2020-09-22 20:38:14.000000000 
+0200
@@ -1,5 +1,7 @@
-load File.expand_path("../fixture_helper.rb", __FILE__)
+# frozen_string_literal: true
 
-PumaWorkerKiller.enable_rolling_restart(1) # 1 second
+load File.expand_path('fixture_helper.rb', __dir__)
+
+PumaWorkerKiller.enable_rolling_restart(1, 0..5.0) # 1 second, short 1-5s 
splay.
 
 run HelloWorldApp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/puma_worker_killer_test.rb 
new/test/puma_worker_killer_test.rb
--- old/test/puma_worker_killer_test.rb 2019-06-26 21:06:55.000000000 +0200
+++ new/test/puma_worker_killer_test.rb 2020-09-22 20:38:14.000000000 +0200
@@ -1,76 +1,104 @@
+# frozen_string_literal: true
+
 require 'test_helper'
 
 class PumaWorkerKillerTest < Test::Unit::TestCase
-
   def test_starts
     port     = 0 # 
http://stackoverflow.com/questions/200484/how-do-you-find-a-free-tcp-server-port-using-ruby
-    command  = "bundle exec puma #{ fixture_path.join("default.ru") } -t 1:1 
-w 2 --preload --debug -p #{ port }"
-    options  = { wait_for: "booted", timeout: 5, env: { "PUMA_FREQUENCY" => 1 
} }
+    command  = "bundle exec puma #{fixture_path.join("default.ru")} -t 1:1 -w 
2 --preload --debug -p #{port}"
+    options  = { wait_for: 'booted', timeout: 5, env: { 'PUMA_FREQUENCY' => 1 
} }
 
     WaitForIt.new(command, options) do |spawn|
-      assert_contains(spawn, "PumaWorkerKiller")
+      assert_contains(spawn, 'PumaWorkerKiller')
     end
   end
 
   def test_without_preload
     port     = 0 # 
http://stackoverflow.com/questions/200484/how-do-you-find-a-free-tcp-server-port-using-ruby
-    command  = "bundle exec puma #{ fixture_path.join("default.ru") } -t 1:1 
-w 2 --debug -p #{ port } -C #{ 
fixture_path.join("config/puma_worker_killer_start.rb") }"
-    options  = { wait_for: "booted", timeout: 10, env: { "PUMA_FREQUENCY" => 1 
} }
+    command  = "bundle exec puma #{fixture_path.join("default.ru")} -t 1:1 -w 
2 --debug -p #{port} -C 
#{fixture_path.join("config/puma_worker_killer_start.rb")}"
+    options  = { wait_for: 'booted', timeout: 10, env: { 'PUMA_FREQUENCY' => 1 
} }
 
     WaitForIt.new(command, options) do |spawn|
-      assert_contains(spawn, "PumaWorkerKiller")
+      assert_contains(spawn, 'PumaWorkerKiller')
     end
   end
 
   def test_kills_large_app
-    file     = fixture_path.join("big.ru")
+    file     = fixture_path.join('big.ru')
     port     = 0
-    command  = "bundle exec puma #{ file } -t 1:1 -w 2 --preload --debug -p #{ 
port }"
-    options  = { wait_for: "booted", timeout: 5, env: { "PUMA_FREQUENCY" => 1, 
'PUMA_RAM' => 1} }
+    command  = "bundle exec puma #{file} -t 1:1 -w 2 --preload --debug -p 
#{port}"
+    options  = { wait_for: 'booted', timeout: 5, env: { 'PUMA_FREQUENCY' => 1, 
'PUMA_RAM' => 1 } }
 
     WaitForIt.new(command, options) do |spawn|
-      assert_contains(spawn, "Out of memory")
+      assert_contains(spawn, 'Out of memory')
     end
   end
 
   def test_pre_term
-    file     = fixture_path.join("pre_term.ru")
+    file     = fixture_path.join('pre_term.ru')
     port     = 0
-    command  = "bundle exec puma #{ file } -t 1:1 -w 2 --preload --debug -p #{ 
port }"
-    options  = { wait_for: "booted", timeout: 5, env: { "PUMA_FREQUENCY" => 1, 
'PUMA_RAM' => 1} }
+    command  = "bundle exec puma #{file} -t 1:1 -w 2 --preload --debug -p 
#{port}"
+    options  = { wait_for: 'booted', timeout: 5, env: { 'PUMA_FREQUENCY' => 1, 
'PUMA_RAM' => 1 } }
 
     WaitForIt.new(command, options) do |spawn|
-      assert_contains(spawn, "Out of memory")
-      assert_contains(spawn, "About to terminate worker:") # defined in 
pre_term.ru
+      assert_contains(spawn, 'Out of memory')
+      assert_contains(spawn, 'About to terminate worker:') # defined in 
pre_term.ru
     end
   end
 
   def test_on_calculation
-    file     = fixture_path.join("on_calculation.ru")
+    file     = fixture_path.join('on_calculation.ru')
     port     = 0
-    command  = "bundle exec puma #{ file } -t 1:1 -w 2 --preload --debug -p #{ 
port }"
-    options  = { wait_for: "booted", timeout: 5, env: { "PUMA_FREQUENCY" => 1, 
'PUMA_RAM' => 1} }
+    command  = "bundle exec puma #{file} -t 1:1 -w 2 --preload --debug -p 
#{port}"
+    options  = { wait_for: 'booted', timeout: 5, env: { 'PUMA_FREQUENCY' => 1, 
'PUMA_RAM' => 1 } }
 
     WaitForIt.new(command, options) do |spawn|
-      assert_contains(spawn, "Out of memory")
-      assert_contains(spawn, "Current memory footprint:") # defined in 
on_calculate.ru
+      assert_contains(spawn, 'Out of memory')
+      assert_contains(spawn, 'Current memory footprint:') # defined in 
on_calculate.ru
     end
   end
 
   def assert_contains(spawn, string)
-    assert spawn.wait(string), "Expected logs to contain '#{string}' but it 
did not, contents: #{ spawn.log.read }"
+    assert spawn.wait(string), "Expected logs to contain '#{string}' but it 
did not, contents: #{spawn.log.read}"
   end
 
   def test_rolling_restart
+    file     = fixture_path.join('rolling_restart.ru')
+    port     = 0
+    command  = "bundle exec puma #{file} -t 1:1 -w 2 --preload --debug -p 
#{port}"
+    puts command.inspect
+    options = { wait_for: 'booted', timeout: 15, env: {} }
+
+    WaitForIt.new(command, options) do |spawn|
+      assert_contains(spawn, 'Rolling Restart')
+    end
+  end
+
+  def test_rolling_restart_worker_kill_check
+    file     = fixture_path.join('rolling_restart.ru')
+    port     = 0
+    command  = "bundle exec puma #{file} -t 1:1 -w 1 --preload --debug -p 
#{port}"
+    puts command.inspect
+    options = { wait_for: 'booted', timeout: 120, env: {} }
+
+    WaitForIt.new(command, options) do |spawn|
+      # at least 2 matches for TERM (so we set a timeout value longer - 120sec)
+      spawn.wait!(/TERM.*TERM/m)
+      term_ids = spawn.log.read.scan(/TERM to pid (\d*)/)
+      assert term_ids.sort == term_ids.uniq.sort
+    end
+  end
 
-    file     = fixture_path.join("rolling_restart.ru")
+  def test_rolling_pre_term
+    file     = fixture_path.join('rolling_pre_term.ru')
     port     = 0
-    command  = "bundle exec puma #{ file } -t 1:1 -w 2 --preload --debug -p #{ 
port }"
+    command  = "bundle exec puma #{file} -t 1:1 -w 2 --preload --debug -p 
#{port}"
     puts command.inspect
-    options  = { wait_for: "booted", timeout: 15, env: { } }
+    options = { wait_for: 'booted', timeout: 15, env: {} }
 
     WaitForIt.new(command, options) do |spawn|
-      assert_contains(spawn, "Rolling Restart")
+      assert_contains(spawn, 'Rolling Restart')
+      assert_contains(spawn, 'About to terminate (rolling) worker:') # defined 
in rolling_pre_term.ru
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/test_helper.rb new/test/test_helper.rb
--- old/test/test_helper.rb     2019-06-26 21:06:55.000000000 +0200
+++ new/test/test_helper.rb     2020-09-22 20:38:14.000000000 +0200
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 Bundler.require
 
 require 'puma_worker_killer'
@@ -5,5 +7,5 @@
 require 'wait_for_it'
 
 def fixture_path
-  Pathname.new(File.expand_path("../fixtures", __FILE__))
+  Pathname.new(File.expand_path('fixtures', __dir__))
 end


Reply via email to