unicorn_wrangler 0.5.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f027def0eaa75e21daf9efc322a1be988248b5cd117d12eb2ddfadc10494e4d7
4
- data.tar.gz: a765f7d06d90f8ef448ae1ac87eeb0fc01dddac587dce8d1c69f00acbf6c0164
3
+ metadata.gz: 5bc72c4eced8c3d3036e8b63f27b6ac010a02685c3d9490f5756753d1a4d0e3c
4
+ data.tar.gz: e7dad93958d88498ecbd4b97bb2c575a20758f16acd4d6e53ebf4644b3da09ba
5
5
  SHA512:
6
- metadata.gz: 91787cc20b2bafa1334af58dc5bc29985c3f7d165451cfd36fb45e5d63069ce36525f4d63f2a27fb09fdc29215aab0dcb62ad8cacf0e1cae067b5a20e4740188
7
- data.tar.gz: 7b6ca2549873589cd9c837affafcc9a9fc07878476c7554f785b20c30b132a1d9e1f9ad12c24af9c16b27d40dae70cd47a7581f28642ea643e055bf9ff95d2ca
6
+ metadata.gz: 1014ebefa5bdc8de9e9b90ff8471972d165ef2f2d1fa5bd966ecf29522ee38c1b014f110aef1f9ffe81908a0c734e1c14a76f4e6292cb5f2a0d4601b29b5e204
7
+ data.tar.gz: 59a04f50a950e8556a7ff6337d6fa8252b14394beb3cb448228df024051ec21110201af1271a7f56a2615671ade2965d91c4eaf7c942135e248b4955898172c5
@@ -0,0 +1,50 @@
1
+ # Read RSS based on the OS we are in. When in linux, we can read the proc status file and parse out
2
+ # the RSS which is much faster than forking+execing ps.
3
+ module UnicornWrangler
4
+ class RssReader
5
+ LINUX = RbConfig::CONFIG['host_os'].start_with?('linux')
6
+ PS_CMD = 'ps -o rss= -p %d'.freeze
7
+ VM_RSS = /^VmRSS:\s+(\d+)\s+(\w+)/
8
+ UNITS = {
9
+ b: 1024**0,
10
+ kb: 1024**1,
11
+ mb: 1024**2,
12
+ gb: 1024**3,
13
+ tb: 1024**4,
14
+ }.freeze
15
+
16
+ def initialize(logger:)
17
+ @logger = logger
18
+ end
19
+
20
+ # Returns RSS in megabytes; should work on Linux and Mac OS X
21
+ def rss(pid: Process.pid)
22
+ LINUX ? rss_linux(pid) : rss_posix(pid)
23
+ end
24
+
25
+ private
26
+
27
+ # Fork/exec ps and parse result.
28
+ # Should work on any system with POSIX ps.
29
+ # ~4ms
30
+ # returns kb but we want mb
31
+ def rss_posix(pid)
32
+ `#{PS_CMD % [pid]}`.to_i / 1024
33
+ end
34
+
35
+ # Read from /proc/$pid/status. Linux only.
36
+ # ~100x faster and doesn't incur significant memory cost.
37
+ # file returns variable units, we want mb
38
+ def rss_linux(pid)
39
+ File.read("/proc/#{pid}/status").match(VM_RSS) do |match|
40
+ value, magnitude = match[1].to_i, UNITS.fetch(match[2].downcase.to_sym)
41
+
42
+ value * magnitude / UNITS.fetch(:mb)
43
+ end
44
+ rescue
45
+ # If the given pid is dead, file will not be found
46
+ @logger.warn 'Failed to read RSS from /proc, falling back to exec+ps' if @logger
47
+ rss_posix(pid)
48
+ end
49
+ end
50
+ end
@@ -1,3 +1,3 @@
1
1
  module UnicornWrangler
2
- VERSION = "0.5.2"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -3,12 +3,13 @@
3
3
  # - runs GC out of band (does not block requests)
4
4
 
5
5
  require 'benchmark'
6
+ require 'unicorn_wrangler/rss_reader'
6
7
 
7
8
  module UnicornWrangler
8
9
  STATS_NAMESPACE = 'unicorn'
9
10
 
10
11
  class << self
11
- attr_reader :handlers
12
+ attr_reader :handlers, :requests, :request_time
12
13
  attr_accessor :sending_myself_term
13
14
 
14
15
  # called from unicorn config (usually config/unicorn.rb)
@@ -25,7 +26,7 @@ module UnicornWrangler
25
26
  logger.info "Sending stats to under #{stats.namespace}.#{STATS_NAMESPACE}" if stats
26
27
  @handlers = []
27
28
  @handlers << RequestKiller.new(logger, stats, kill_after_requests) if kill_after_requests
28
- @handlers << OutOfMemoryKiller.new(logger, stats, kill_on_too_much_memory) if kill_on_too_much_memory
29
+ @handlers << OutOfMemoryKiller.new(logger, stats, **kill_on_too_much_memory) if kill_on_too_much_memory
29
30
  @handlers << OutOfBandGC.new(logger, stats, gc_after_request_time) if gc_after_request_time
30
31
 
31
32
  @hooks = {}
@@ -109,6 +110,7 @@ module UnicornWrangler
109
110
  def initialize(logger, stats)
110
111
  @logger = logger
111
112
  @stats = stats
113
+ @rss_reader = RssReader.new(logger: logger)
112
114
  end
113
115
 
114
116
  private
@@ -130,9 +132,9 @@ module UnicornWrangler
130
132
  UnicornWrangler.kill_worker
131
133
  end
132
134
 
133
- # expensive, do not run on every request
135
+ # RSS memory in MB. Can be expensive, do not run on every request
134
136
  def used_memory
135
- `ps -o rss= -p #{Process.pid}`.to_i / 1024
137
+ @rss_reader.rss
136
138
  end
137
139
 
138
140
  def report_status(status, reason, memory, requests, request_time, log_level = :debug)
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn_wrangler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-22 00:00:00.000000000 Z
11
+ date: 2022-04-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description:
13
+ description:
14
14
  email: michael@grosser.it
15
15
  executables: []
16
16
  extensions: []
@@ -18,12 +18,13 @@ extra_rdoc_files: []
18
18
  files:
19
19
  - MIT-LICENSE
20
20
  - lib/unicorn_wrangler.rb
21
+ - lib/unicorn_wrangler/rss_reader.rb
21
22
  - lib/unicorn_wrangler/version.rb
22
23
  homepage: https://github.com/grosser/unicorn_wrangler
23
24
  licenses:
24
25
  - MIT
25
26
  metadata: {}
26
- post_install_message:
27
+ post_install_message:
27
28
  rdoc_options: []
28
29
  require_paths:
29
30
  - lib
@@ -31,15 +32,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
31
32
  requirements:
32
33
  - - ">="
33
34
  - !ruby/object:Gem::Version
34
- version: 2.2.0
35
+ version: 2.7.0
35
36
  required_rubygems_version: !ruby/object:Gem::Requirement
36
37
  requirements:
37
38
  - - ">="
38
39
  - !ruby/object:Gem::Version
39
40
  version: '0'
40
41
  requirements: []
41
- rubygems_version: 3.1.4
42
- signing_key:
42
+ rubygems_version: 3.3.3
43
+ signing_key:
43
44
  specification_version: 4
44
45
  summary: 'Unicorn: out of band GC / restart on max memory bloat / restart after X
45
46
  requests'