Hello community,

here is the log from the commit of package rubygem-puma_worker_killer for 
openSUSE:Factory checked in at 2017-06-08 15:01:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-puma_worker_killer (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-puma_worker_killer.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-puma_worker_killer"

Thu Jun  8 15:01:32 2017 rev:3 rq:497708 version:0.1.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/rubygem-puma_worker_killer/rubygem-puma_worker_killer.changes
    2016-11-07 12:23:16.000000000 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-puma_worker_killer.new/rubygem-puma_worker_killer.changes
       2017-06-08 15:01:33.419268918 +0200
@@ -1,0 +2,10 @@
+Tue May 23 10:11:52 UTC 2017 - [email protected]
+
+- updated to version 0.1.0
+ see installed CHANGELOG.md
+
+  ## 0.1.0
+  
+  - Emit extra data via `pre_term` callback before puma worker killer 
terminates a worker #49.
+
+-------------------------------------------------------------------

Old:
----
  puma_worker_killer-0.0.7.gem

New:
----
  puma_worker_killer-0.1.0.gem

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

Other differences:
------------------
++++++ rubygem-puma_worker_killer.spec ++++++
--- /var/tmp/diff_new_pack.vzaGLb/_old  2017-06-08 15:01:34.147166190 +0200
+++ /var/tmp/diff_new_pack.vzaGLb/_new  2017-06-08 15:01:34.147166190 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-puma_worker_killer
 #
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # 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.0.7
+Version:        0.1.0
 Release:        0
 %define mod_name puma_worker_killer
 %define mod_full_name %{mod_name}-%{version}

++++++ puma_worker_killer-0.0.7.gem -> puma_worker_killer-0.1.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md    2016-10-13 16:56:01.000000000 +0200
+++ new/CHANGELOG.md    2017-05-12 17:28:39.000000000 +0200
@@ -1,3 +1,7 @@
+## 0.1.0
+
+- Emit extra data via `pre_term` callback before puma worker killer terminates 
a worker #49.
+
 ## 0.0.7
 
 - Logging is configurable #41
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2016-10-13 16:56:01.000000000 +0200
+++ new/README.md       2017-05-12 17:28:39.000000000 +0200
@@ -34,6 +34,8 @@
 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:
 
 ```ruby
+# config/puma.rb
+
 before_fork do
   require 'puma_worker_killer'
 
@@ -103,10 +105,30 @@
   config.rolling_restart_frequency = 12 * 3600 # 12 hours in seconds
   config.reaper_status_logs = true # setting this to false will not log lines 
like:
   # PumaWorkerKiller: Consuming 54.34765625 mb with master and 2 workers.
+
+  config.pre_term = -> (worker) { puts "Worker #{worker.inspect} being killed" 
}
 end
 PumaWorkerKiller.start
 ```
 
+### pre_term
+
+`config.pre_term` will be called just prior to worker termination with the 
worker that is about to be terminated. This may be useful to use in keeping 
track of metrics, time of day workers are restarted, etc.
+
+By default Puma Worker Killer will emit a log when a worker is being killed
+
+```
+PumaWorkerKiller: Out of memory. 5 workers consuming total: 500 mb out of max: 
450 mb. Sending TERM to pid 23 consuming 53 mb.
+```
+
+or
+
+```
+PumaWorkerKiller: Rolling Restart. 5 workers consuming total: 650mb mb. 
Sending TERM to pid 34.
+```
+
+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.
+
 ## Attention
 
 If you start puma as a daemon, to add puma worker killer config into puma 
config file, rather than into initializers:
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/puma_memory.rb 
new/lib/puma_worker_killer/puma_memory.rb
--- old/lib/puma_worker_killer/puma_memory.rb   2016-10-13 16:56:01.000000000 
+0200
+++ new/lib/puma_worker_killer/puma_memory.rb   2017-05-12 17:28:39.000000000 
+0200
@@ -12,6 +12,10 @@
       workers.size
     end
 
+    def term_worker(worker)
+      worker.term
+    end
+
     def term_largest_worker
       largest_worker.term
     #   Process.wait(largest_worker.pid)
@@ -78,4 +82,4 @@
       end
     end
   end
-end
\ No newline at end of file
+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        2016-10-13 16:56:01.000000000 
+0200
+++ new/lib/puma_worker_killer/reaper.rb        2017-05-12 17:28:39.000000000 
+0200
@@ -1,9 +1,10 @@
 module PumaWorkerKiller
   class Reaper
-    def initialize(max_ram, master = nil, reaper_status_logs = true)
+    def initialize(max_ram, master = nil, reaper_status_logs = true, pre_term)
       @cluster = PumaWorkerKiller::PumaMemory.new(master)
       @max_ram = max_ram
       @reaper_status_logs = reaper_status_logs
+      @pre_term = pre_term
     end
 
     # used for tes
@@ -15,7 +16,18 @@
       return false if @cluster.workers_stopped?
       if (total = get_total_memory) > @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."
-        @cluster.term_largest_worker
+
+        # Fetch the largest_worker so that both `@pre_term` and `term_worker` 
are called with the same worker
+        # Avoids a race condition where:
+        #   Worker A consume 100 mb memory
+        #   Worker B consume 99 mb memory
+        #   pre_term gets called with Worker A
+        #   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)
+        @cluster.term_worker(largest_worker)
+
       elsif @reaper_status_logs
         @cluster.master.log "PumaWorkerKiller: Consuming #{total} mb with 
master and #{@cluster.workers.count} workers."
       end
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       2016-10-13 
16:56:01.000000000 +0200
+++ new/lib/puma_worker_killer/rolling_restart.rb       2017-05-12 
17:28:39.000000000 +0200
@@ -12,7 +12,7 @@
     def reap(wait_between_worker_kill = 60) # seconds
       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 out 
of max: #{@max_ram} mb. Sending TERM to pid #{worker.pid}."
+        @cluster.master.log "PumaWorkerKiller: Rolling Restart. 
#{@cluster.workers.count} workers consuming total: #{ get_total_memory } mb. 
Sending TERM to pid #{worker.pid}."
         worker.term
         sleep wait_between_worker_kill
       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       2016-10-13 16:56:01.000000000 
+0200
+++ new/lib/puma_worker_killer/version.rb       2017-05-12 17:28:39.000000000 
+0200
@@ -1,3 +1,3 @@
 module PumaWorkerKiller
-  VERSION = "0.0.7"
+  VERSION = "0.1.0"
 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       2016-10-13 16:56:01.000000000 +0200
+++ new/lib/puma_worker_killer.rb       2017-05-12 17:28:39.000000000 +0200
@@ -3,19 +3,20 @@
 module PumaWorkerKiller
   extend self
 
-  attr_accessor :ram, :frequency, :percent_usage, :rolling_restart_frequency, 
:reaper_status_logs
+  attr_accessor :ram, :frequency, :percent_usage, :rolling_restart_frequency, 
:reaper_status_logs, :pre_term
   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.reaper_status_logs = true
+  self.pre_term = lambda { |_| } # nop
 
   def config
     yield self
   end
 
-  def reaper(ram = self.ram, percent = self.percent_usage, reaper_status_logs 
= self.reaper_status_logs)
-    Reaper.new(ram * percent_usage, nil, reaper_status_logs)
+  def reaper(ram = self.ram, percent = self.percent_usage, reaper_status_logs 
= self.reaper_status_logs, pre_term = self.pre_term)
+    Reaper.new(ram * percent_usage, nil, reaper_status_logs, pre_term)
   end
 
   def start(frequency = self.frequency, reaper = self.reaper)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2016-10-13 16:56:01.000000000 +0200
+++ new/metadata        2017-05-12 17:28:39.000000000 +0200
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: puma_worker_killer
 version: !ruby/object:Gem::Version
-  version: 0.0.7
+  version: 0.1.0
 platform: ruby
 authors:
 - Richard Schneeman
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2016-10-13 00:00:00.000000000 Z
+date: 2017-05-12 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: puma
@@ -124,6 +124,7 @@
 - test/fixtures/config/puma_worker_killer_start.rb
 - test/fixtures/default.ru
 - test/fixtures/fixture_helper.rb
+- test/fixtures/pre_term.ru
 - test/fixtures/rolling_restart.ru
 - test/puma_worker_killer_test.rb
 - test/test_helper.rb
@@ -147,7 +148,7 @@
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.6.4
+rubygems_version: 2.6.11
 signing_key: 
 specification_version: 4
 summary: If you have a memory leak in your web code puma_worker_killer can 
keep it
@@ -157,7 +158,7 @@
 - test/fixtures/config/puma_worker_killer_start.rb
 - test/fixtures/default.ru
 - test/fixtures/fixture_helper.rb
+- test/fixtures/pre_term.ru
 - test/fixtures/rolling_restart.ru
 - test/puma_worker_killer_test.rb
 - test/test_helper.rb
-has_rdoc: 
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       1970-01-01 01:00:00.000000000 +0100
+++ new/test/fixtures/pre_term.ru       2017-05-12 17:28:39.000000000 +0200
@@ -0,0 +1,8 @@
+load File.expand_path("../fixture_helper.rb", __FILE__)
+
+PumaWorkerKiller.config do |config|
+  config.pre_term = lambda { |worker| puts("About to terminate worker: 
#{worker.inspect}") }
+end
+PumaWorkerKiller.start
+
+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 2016-10-13 16:56:01.000000000 +0200
+++ new/test/puma_worker_killer_test.rb 2017-05-12 17:28:39.000000000 +0200
@@ -33,6 +33,18 @@
     end
   end
 
+  def test_pre_term
+    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} }
+
+    WaitForIt.new(command, options) do |spawn|
+      assert_contains(spawn, "Out of memory")
+      assert_contains(spawn, "About to terminate worker:") # defined in 
pre_term.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 }"
   end
@@ -50,4 +62,3 @@
     end
   end
 end
-


Reply via email to