resque-multi-job-forks 0.4.1 → 0.4.2
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 +7 -0
- data/lib/resque-multi-job-forks.rb +15 -2
- data/lib/resque/plugins/multi_job_forks/rss_reader.rb +44 -0
- data/test/test_rss_reader.rb +34 -0
- metadata +20 -33
checksums.yaml
ADDED
|
@@ -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 ?
|
|
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.
|
|
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:
|
|
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.
|
|
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.
|
|
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:
|
|
105
|
+
rubygems_version: 2.2.2
|
|
120
106
|
signing_key:
|
|
121
|
-
specification_version:
|
|
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
|