resque-multi-job-forks 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fdc96f5c13d05b9537644689803bc6b95a49a232
4
+ data.tar.gz: 15d6f6dce37c4f2c47c3b202b29ade84efd12aeb
5
+ SHA512:
6
+ metadata.gz: bfd6fe81a46c5bd9e4cbec35b8b29af8f274bcb31a27340edeb5fb984bc14b094b79709df91d2e09eceb9dd75a6d2c2708f9021bdb81034c23be2916dc83f026
7
+ data.tar.gz: 6766f1baf6a4866e36ed7096a18d509e4599ad78daf0e29b9dfc94fce46ad87b26431d6f25f4df77a6668284a3926741dfd2a4d94da62ce5bcfc2b90081637d2
@@ -1,10 +1,13 @@
1
1
  require 'resque'
2
2
  require 'resque/worker'
3
+ require 'resque/plugins/multi_job_forks/rss_reader'
3
4
 
4
5
  module Resque
5
6
  class Worker
7
+ include Plugins::MultiJobForks::RssReader
6
8
  attr_accessor :seconds_per_fork
7
9
  attr_accessor :jobs_per_fork
10
+ attr_accessor :memory_threshold
8
11
  attr_reader :jobs_processed
9
12
 
10
13
  def self.multi_jobs_per_fork?
@@ -78,7 +81,7 @@ module Resque
78
81
  end
79
82
 
80
83
  def release_fork
81
- log "jobs processed by child: #{jobs_processed}"
84
+ log "jobs processed by child: #{jobs_processed}; rss: #{rss}"
82
85
  run_hook :before_child_exit, self
83
86
  Resque.after_fork, Resque.before_fork = *@suppressed_fork_hooks
84
87
  @release_fork_limit = @jobs_processed = @cant_fork = nil
@@ -91,7 +94,7 @@ module Resque
91
94
  end
92
95
 
93
96
  def fork_job_limit_reached?
94
- fork_job_limit_remaining <= 0 ? true : false
97
+ fork_job_limit_remaining <= 0 || fork_job_over_memory_threshold?
95
98
  end
96
99
 
97
100
  def fork_job_limit_remaining
@@ -109,6 +112,16 @@ module Resque
109
112
  def jobs_per_fork
110
113
  @jobs_per_fork ||= ENV['JOBS_PER_FORK'].nil? ? nil : ENV['JOBS_PER_FORK'].to_i
111
114
  end
115
+
116
+ def fork_job_over_memory_threshold?
117
+ !!(memory_threshold && rss > memory_threshold)
118
+ end
119
+
120
+ def memory_threshold
121
+ @memory_threshold ||= ENV["RESQUE_MEM_THRESHOLD"].to_i
122
+ @memory_threshold > 0 && @memory_threshold
123
+ end
124
+
112
125
  end
113
126
 
114
127
  # the `before_child_exit` hook will run in the child process
@@ -0,0 +1,44 @@
1
+ module Resque
2
+ module Plugins
3
+ module MultiJobForks
4
+ module RssReader
5
+ extend self
6
+ LINUX = RbConfig::CONFIG['host_os'].start_with?('linux')
7
+ PS_CMD = "ps -o rss= -p %d".freeze
8
+ UNITS = {
9
+ b: 1024**-1,
10
+ kb: 1024**0,
11
+ mb: 1024**1,
12
+ gb: 1024**2,
13
+ tb: 1024**3,
14
+ }.freeze
15
+
16
+ # Returns RSS in Kb; should work on Linux and Mac OS X
17
+ def rss(pid=Process.pid)
18
+ LINUX ? rss_linux(pid) : rss_posix(pid)
19
+ end
20
+
21
+ # Fork/exec ps and parse result.
22
+ # Should work on any system with POSIX ps.
23
+ def rss_posix(pid=Process.pid)
24
+ `#{PS_CMD % [pid]}`.to_i
25
+ end
26
+
27
+ # Read from /proc/$pid/status. Linux only.
28
+ # MUCH faster and doesn't incur significant memory cost.
29
+ def rss_linux(pid=Process.pid)
30
+ File.open("/proc/#{pid}/status") do |file|
31
+ file.each_line do |line|
32
+ if line[/^VmRSS/]
33
+ _,c,u = line.split
34
+ return (c.to_i * UNITS[u.downcase.to_sym]).to_i
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), '/helper')
2
+
3
+ class TestRssReader < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @object = Object.new
7
+ @object.extend Resque::Plugins::MultiJobForks::RssReader
8
+ end
9
+
10
+ def test_current_process_rss
11
+ rss = @object.rss
12
+ # not a very strict test, but have you ever seen a ruby process < 1Mb?
13
+ # the "real" test is manual verification via top/ps/htop
14
+ assert_equal Fixnum, rss.class
15
+ assert @object.rss > 1000
16
+ end
17
+
18
+ def test_rss_other_processes
19
+ rss = @object.rss(1) # init is guaranteed to exist
20
+ assert_equal Fixnum, rss.class
21
+ assert @object.rss > 1000
22
+ end
23
+
24
+ def test_rss_posix
25
+ assert @object.rss_posix > 1000
26
+ end
27
+
28
+ if Resque::Plugins::MultiJobForks::RssReader::LINUX
29
+ def test_rss_linux
30
+ assert @object.rss_linux > 1000
31
+ end
32
+ end
33
+
34
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-multi-job-forks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
5
- prerelease:
4
+ version: 0.4.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Mick Staugaard
@@ -11,70 +10,62 @@ authors:
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2013-10-07 00:00:00.000000000 Z
13
+ date: 2014-04-01 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: resque
18
17
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
18
  requirements:
21
- - - ~>
19
+ - - "~>"
22
20
  - !ruby/object:Gem::Version
23
- version: '1.24'
21
+ version: '1.22'
24
22
  type: :runtime
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
25
  requirements:
29
- - - ~>
26
+ - - "~>"
30
27
  - !ruby/object:Gem::Version
31
- version: '1.24'
28
+ version: '1.22'
32
29
  - !ruby/object:Gem::Dependency
33
30
  name: json
34
31
  requirement: !ruby/object:Gem::Requirement
35
- none: false
36
32
  requirements:
37
- - - ! '>='
33
+ - - ">="
38
34
  - !ruby/object:Gem::Version
39
35
  version: '0'
40
36
  type: :runtime
41
37
  prerelease: false
42
38
  version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
39
  requirements:
45
- - - ! '>='
40
+ - - ">="
46
41
  - !ruby/object:Gem::Version
47
42
  version: '0'
48
43
  - !ruby/object:Gem::Dependency
49
44
  name: rake
50
45
  requirement: !ruby/object:Gem::Requirement
51
- none: false
52
46
  requirements:
53
- - - ! '>='
47
+ - - ">="
54
48
  - !ruby/object:Gem::Version
55
49
  version: '0'
56
50
  type: :development
57
51
  prerelease: false
58
52
  version_requirements: !ruby/object:Gem::Requirement
59
- none: false
60
53
  requirements:
61
- - - ! '>='
54
+ - - ">="
62
55
  - !ruby/object:Gem::Version
63
56
  version: '0'
64
57
  - !ruby/object:Gem::Dependency
65
58
  name: bundler
66
59
  requirement: !ruby/object:Gem::Requirement
67
- none: false
68
60
  requirements:
69
- - - ! '>='
61
+ - - ">="
70
62
  - !ruby/object:Gem::Version
71
63
  version: '0'
72
64
  type: :development
73
65
  prerelease: false
74
66
  version_requirements: !ruby/object:Gem::Requirement
75
- none: false
76
67
  requirements:
77
- - - ! '>='
68
+ - - ">="
78
69
  - !ruby/object:Gem::Version
79
70
  version: '0'
80
71
  description: When your resque jobs are frequent and fast, the overhead of forking
@@ -88,38 +79,34 @@ extensions: []
88
79
  extra_rdoc_files: []
89
80
  files:
90
81
  - lib/resque-multi-job-forks.rb
82
+ - lib/resque/plugins/multi_job_forks/rss_reader.rb
91
83
  - test/helper.rb
92
84
  - test/test_resque-multi-job-forks.rb
85
+ - test/test_rss_reader.rb
93
86
  homepage: http://github.com/staugaard/resque-multi-job-forks
94
87
  licenses: []
88
+ metadata: {}
95
89
  post_install_message:
96
90
  rdoc_options: []
97
91
  require_paths:
98
92
  - lib
99
93
  required_ruby_version: !ruby/object:Gem::Requirement
100
- none: false
101
94
  requirements:
102
- - - ! '>='
95
+ - - ">="
103
96
  - !ruby/object:Gem::Version
104
97
  version: '0'
105
- segments:
106
- - 0
107
- hash: 4214525788567926268
108
98
  required_rubygems_version: !ruby/object:Gem::Requirement
109
- none: false
110
99
  requirements:
111
- - - ! '>='
100
+ - - ">="
112
101
  - !ruby/object:Gem::Version
113
102
  version: '0'
114
- segments:
115
- - 0
116
- hash: 4214525788567926268
117
103
  requirements: []
118
104
  rubyforge_project:
119
- rubygems_version: 1.8.25
105
+ rubygems_version: 2.2.2
120
106
  signing_key:
121
- specification_version: 3
107
+ specification_version: 4
122
108
  summary: Have your resque workers process more that one job
123
109
  test_files:
124
110
  - test/helper.rb
125
111
  - test/test_resque-multi-job-forks.rb
112
+ - test/test_rss_reader.rb