tunemygc 1.0.55 → 1.0.56
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 +4 -4
- data/Gemfile.lock +4 -1
- data/README.md +2 -2
- data/lib/tunemygc/spies/delayed_job.rb +35 -0
- data/lib/tunemygc/spies.rb +11 -2
- data/lib/tunemygc/version.rb +1 -1
- data/test/delayed_job_test_backend.rb +117 -0
- data/test/{test_activejob_interposer.rb → test_active_job_interposer.rb} +0 -0
- data/test/test_delayed_job_interposer.rb +96 -0
- data/tunemygc.gemspec +1 -0
- metadata +29 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7729fb0e74aeaa4d3015d0e2204c4aaf07c140c
|
4
|
+
data.tar.gz: 73ba3d4ea9b191a881f69eb32477d7fb055b512d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec0ad98014be93b9416c1d786c09194b24300947a02fe305c5e5d06bc098c9ca5a4928e03523c2697675f7b0286e69e187adc2819a4fdbdb9c0b343b75509018
|
7
|
+
data.tar.gz: 9128687fbac2a36cb712c1fe0005f4b228f10b97785408d98b2f57f84078a6102268a100eb3148b3448bb6c72cbff1a072646a138cc16930bf6eb2a194fd8a8f
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tunemygc (1.0.
|
4
|
+
tunemygc (1.0.56)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -46,6 +46,8 @@ GEM
|
|
46
46
|
builder (3.2.2)
|
47
47
|
crack (0.4.2)
|
48
48
|
safe_yaml (~> 1.0.0)
|
49
|
+
delayed_job (4.0.6)
|
50
|
+
activesupport (>= 3.0, < 5.0)
|
49
51
|
erubis (2.7.0)
|
50
52
|
globalid (0.3.0)
|
51
53
|
activesupport (>= 4.1.0)
|
@@ -117,6 +119,7 @@ PLATFORMS
|
|
117
119
|
DEPENDENCIES
|
118
120
|
activejob (~> 4.2, >= 4.2.0)
|
119
121
|
activesupport (~> 4.1)
|
122
|
+
delayed_job (~> 4.0.6, >= 4.0.6)
|
120
123
|
rails
|
121
124
|
rake (~> 10.3)
|
122
125
|
rake-compiler (~> 0.9, >= 0.9.5)
|
data/README.md
CHANGED
@@ -108,9 +108,9 @@ And after some profiling requests, when the process terminates, you can visit th
|
|
108
108
|
|
109
109
|
#### Advanced
|
110
110
|
|
111
|
-
* `RUBY_GC_SPY=action_controller` (Spy on the GC for this type of processing. `action_controller`, `active_job`, `que_job`, `minitest` or `rspec` are supported)
|
111
|
+
* `RUBY_GC_SPY=action_controller` (Spy on the GC for this type of processing. `action_controller`, `active_job`, `delayed_job`, `que_job`, `minitest` or `rspec` are supported)
|
112
112
|
|
113
|
-
Defines what type of processing you would like to sample for GC activity. An Action Controller spy is the default, but [ActiveJob](https://github.com/rails/rails/tree/master/activejob), [que](https://github.com/chanks/que), [minitest](https://github.com/seattlerb/minitest) and [rspec](http://rspec.info) are also supported as experimental features.
|
113
|
+
Defines what type of processing you would like to sample for GC activity. An Action Controller spy is the default, but [ActiveJob](https://github.com/rails/rails/tree/master/activejob), [delayed_job](https://github.com/collectiveidea/delayed_job), [que](https://github.com/chanks/que), [minitest](https://github.com/seattlerb/minitest) and [rspec](http://rspec.info) are also supported as experimental features.
|
114
114
|
|
115
115
|
## How do I use this?
|
116
116
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'delayed_job'
|
4
|
+
|
5
|
+
module Delayed
|
6
|
+
module Plugins
|
7
|
+
class TuneMyGcPlugin < Delayed::Plugin
|
8
|
+
callbacks do |lifecycle|
|
9
|
+
lifecycle.around(:invoke_job) do |job, *args, &block|
|
10
|
+
TuneMyGc.processing_started
|
11
|
+
block.call(job, *args)
|
12
|
+
TuneMyGc.processing_ended
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module TuneMyGc
|
20
|
+
module Spies
|
21
|
+
class DelayedJob < TuneMyGc::Spies::Base
|
22
|
+
def install
|
23
|
+
Delayed::Worker.plugins << Delayed::Plugins::TuneMyGcPlugin
|
24
|
+
TuneMyGc.log "hooked: delayed_job"
|
25
|
+
end
|
26
|
+
|
27
|
+
def uninstall
|
28
|
+
TuneMyGc.uninstall_gc_tracepoint
|
29
|
+
TuneMyGc.log "uninstalled GC tracepoint"
|
30
|
+
Delayed::Worker.plugins.delete(Delayed::Plugins::TuneMyGcPlugin)
|
31
|
+
TuneMyGc.log "uninstalled delayed_job spy"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/tunemygc/spies.rb
CHANGED
@@ -8,12 +8,21 @@ module TuneMyGc
|
|
8
8
|
end
|
9
9
|
|
10
10
|
spy :Base, 'base'
|
11
|
+
|
12
|
+
# Web
|
11
13
|
spy :ActionController, 'action_controller'
|
12
|
-
|
13
|
-
|
14
|
+
|
15
|
+
# Manual
|
14
16
|
spy :Manual, 'manual'
|
17
|
+
|
18
|
+
# Tests
|
19
|
+
spy :Minitest, 'minitest'
|
15
20
|
spy :Rspec, 'rspec'
|
21
|
+
|
22
|
+
# Async jobs
|
23
|
+
spy :ActiveJob, 'active_job'
|
16
24
|
spy :QueJob, 'que_job'
|
25
|
+
spy :DelayedJob, 'delayed_job'
|
17
26
|
|
18
27
|
def self.ids
|
19
28
|
current.map do |spy|
|
data/lib/tunemygc/version.rb
CHANGED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
# An in-memory backend suitable only for testing. Tries to behave as if it were an ORM.
|
4
|
+
module Delayed
|
5
|
+
module Backend
|
6
|
+
module Test
|
7
|
+
class Job
|
8
|
+
attr_accessor :id
|
9
|
+
attr_accessor :priority
|
10
|
+
attr_accessor :attempts
|
11
|
+
attr_accessor :handler
|
12
|
+
attr_accessor :last_error
|
13
|
+
attr_accessor :run_at
|
14
|
+
attr_accessor :locked_at
|
15
|
+
attr_accessor :locked_by
|
16
|
+
attr_accessor :failed_at
|
17
|
+
attr_accessor :queue
|
18
|
+
|
19
|
+
include Delayed::Backend::Base
|
20
|
+
|
21
|
+
cattr_accessor :id
|
22
|
+
self.id = 0
|
23
|
+
|
24
|
+
def initialize(hash = {})
|
25
|
+
self.attempts = 0
|
26
|
+
self.priority = 0
|
27
|
+
self.id = (self.class.id += 1)
|
28
|
+
hash.each { |k, v| send(:"#{k}=", v) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.all
|
32
|
+
@jobs ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.count
|
36
|
+
all.size
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.delete_all
|
40
|
+
all.clear
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.create(attrs = {})
|
44
|
+
new(attrs).tap do |o|
|
45
|
+
o.save
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.create!(*args)
|
50
|
+
create(*args)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.clear_locks!(worker_name)
|
54
|
+
all.select { |j| j.locked_by == worker_name }.each do |j|
|
55
|
+
j.locked_by = nil
|
56
|
+
j.locked_at = nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Find a few candidate jobs to run (in case some immediately get locked by others).
|
61
|
+
def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_time) # rubocop:disable CyclomaticComplexity, PerceivedComplexity
|
62
|
+
jobs = all.select do |j|
|
63
|
+
j.run_at <= db_time_now &&
|
64
|
+
(j.locked_at.nil? || j.locked_at < db_time_now - max_run_time || j.locked_by == worker_name) &&
|
65
|
+
!j.failed?
|
66
|
+
end
|
67
|
+
jobs.select! { |j| j.priority <= Worker.max_priority } if Worker.max_priority
|
68
|
+
jobs.select! { |j| j.priority >= Worker.min_priority } if Worker.min_priority
|
69
|
+
jobs.select! { |j| Worker.queues.include?(j.queue) } if Worker.queues.any?
|
70
|
+
jobs.sort_by! { |j| [j.priority, j.run_at] }[0..limit - 1]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Lock this job for this worker.
|
74
|
+
# Returns true if we have the lock, false otherwise.
|
75
|
+
def lock_exclusively!(_max_run_time, worker)
|
76
|
+
now = self.class.db_time_now
|
77
|
+
if locked_by != worker
|
78
|
+
# We don't own this job so we will update the locked_by name and the locked_at
|
79
|
+
self.locked_at = now
|
80
|
+
self.locked_by = worker
|
81
|
+
end
|
82
|
+
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.db_time_now
|
87
|
+
Time.current
|
88
|
+
end
|
89
|
+
|
90
|
+
def update_attributes(attrs = {})
|
91
|
+
attrs.each { |k, v| send(:"#{k}=", v) }
|
92
|
+
save
|
93
|
+
end
|
94
|
+
|
95
|
+
def destroy
|
96
|
+
self.class.all.delete(self)
|
97
|
+
end
|
98
|
+
|
99
|
+
def save
|
100
|
+
self.run_at ||= Time.current
|
101
|
+
|
102
|
+
self.class.all << self unless self.class.all.include?(self)
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
def save!
|
107
|
+
save
|
108
|
+
end
|
109
|
+
|
110
|
+
def reload
|
111
|
+
reset
|
112
|
+
self
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
File without changes
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
4
|
+
require 'delayed_job'
|
5
|
+
|
6
|
+
Delayed::Worker.delay_jobs = false
|
7
|
+
|
8
|
+
NewsletterJob = Struct.new(:text, :emails) do
|
9
|
+
def perform
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestDelayedJobInterposer < TuneMyGcTestCase
|
14
|
+
def setup
|
15
|
+
TuneMyGc.interposer.uninstall
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new([:ActionController])
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_init
|
23
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new([:DelayedJob])
|
24
|
+
interposer = TuneMyGc.interposer
|
25
|
+
assert !interposer.installed
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_install_uninstall
|
29
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new([:DelayedJob])
|
30
|
+
interposer = TuneMyGc.interposer
|
31
|
+
interposer.install
|
32
|
+
interposer.on_initialized
|
33
|
+
assert interposer.installed
|
34
|
+
assert_nil interposer.install
|
35
|
+
|
36
|
+
interposer.uninstall
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_gc_hooks
|
40
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new([:DelayedJob])
|
41
|
+
interposer = TuneMyGc.interposer
|
42
|
+
interposer.install
|
43
|
+
TuneMyGc.interposer.on_initialized
|
44
|
+
|
45
|
+
GC.start(full_mark: true, immediate_sweep: false)
|
46
|
+
GC.start(full_mark: true, immediate_sweep: true)
|
47
|
+
|
48
|
+
stages = []
|
49
|
+
|
50
|
+
while !TuneMyGc.snapshotter.empty?
|
51
|
+
stages << TuneMyGc.snapshotter.deq
|
52
|
+
end
|
53
|
+
|
54
|
+
# Account for incremental GC on 2.2
|
55
|
+
cycles = [:GC_CYCLE_STARTED, :GC_CYCLE_ENTERED]
|
56
|
+
|
57
|
+
assert stages.any?{|s| cycles.include?(s[3]) }
|
58
|
+
|
59
|
+
interposer.uninstall
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_tests_limit
|
63
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new([:DelayedJob])
|
64
|
+
interposer = TuneMyGc.interposer
|
65
|
+
interposer.install
|
66
|
+
TuneMyGc.interposer.on_initialized
|
67
|
+
|
68
|
+
ENV["RUBY_GC_TUNE"] = "2"
|
69
|
+
|
70
|
+
require 'delayed_job_test_backend'
|
71
|
+
Delayed.const_set(:Job, Delayed::Backend::Test::Job)
|
72
|
+
worker = Delayed::Worker.new(:max_priority => nil, :min_priority => nil, :quiet => true)
|
73
|
+
worker.work_off
|
74
|
+
|
75
|
+
run_newsletter_job
|
76
|
+
run_newsletter_job
|
77
|
+
|
78
|
+
stages = []
|
79
|
+
|
80
|
+
while !TuneMyGc.snapshotter.empty?
|
81
|
+
stages << TuneMyGc.snapshotter.deq
|
82
|
+
end
|
83
|
+
|
84
|
+
cycles = [:PROCESSING_STARTED]
|
85
|
+
|
86
|
+
assert stages.any?{|s| cycles.include?(s[3]) }
|
87
|
+
|
88
|
+
interposer.uninstall
|
89
|
+
ensure
|
90
|
+
ENV["RUBY_GC_TUNE"] = "1"
|
91
|
+
end
|
92
|
+
|
93
|
+
def run_newsletter_job
|
94
|
+
Delayed::Job.enqueue NewsletterJob.new("test", %w(lourens@bearmetal.eu))
|
95
|
+
end
|
96
|
+
end
|
data/tunemygc.gemspec
CHANGED
@@ -27,4 +27,5 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_development_dependency('rake-compiler', '~> 0.9', '>= 0.9.5')
|
28
28
|
s.add_development_dependency('webmock', '~> 1.2', '>= 1.2.0')
|
29
29
|
s.add_development_dependency('activejob', '~> 4.2', '>= 4.2.0')
|
30
|
+
s.add_development_dependency('delayed_job', '~> 4.0.6', '>= 4.0.6')
|
30
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tunemygc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.56
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bear Metal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -98,6 +98,26 @@ dependencies:
|
|
98
98
|
- - ">="
|
99
99
|
- !ruby/object:Gem::Version
|
100
100
|
version: 4.2.0
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: delayed_job
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: 4.0.6
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 4.0.6
|
111
|
+
type: :development
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 4.0.6
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: 4.0.6
|
101
121
|
description: Agent for the GC tuning webservice https://www.tunemygc.com - optimal
|
102
122
|
settings for throughput and memory usage of Ruby applications
|
103
123
|
email:
|
@@ -133,6 +153,7 @@ files:
|
|
133
153
|
- lib/tunemygc/spies/action_controller.rb
|
134
154
|
- lib/tunemygc/spies/active_job.rb
|
135
155
|
- lib/tunemygc/spies/base.rb
|
156
|
+
- lib/tunemygc/spies/delayed_job.rb
|
136
157
|
- lib/tunemygc/spies/manual.rb
|
137
158
|
- lib/tunemygc/spies/minitest.rb
|
138
159
|
- lib/tunemygc/spies/que_job.rb
|
@@ -140,11 +161,13 @@ files:
|
|
140
161
|
- lib/tunemygc/subscriber.rb
|
141
162
|
- lib/tunemygc/syncer.rb
|
142
163
|
- lib/tunemygc/version.rb
|
164
|
+
- test/delayed_job_test_backend.rb
|
143
165
|
- test/fixtures.rb
|
144
166
|
- test/helper.rb
|
145
167
|
- test/test_action_controller_interposer.rb
|
146
|
-
- test/
|
168
|
+
- test/test_active_job_interposer.rb
|
147
169
|
- test/test_agent.rb
|
170
|
+
- test/test_delayed_job_interposer.rb
|
148
171
|
- test/test_minitest_interposer.rb
|
149
172
|
- test/test_railtie.rb
|
150
173
|
- test/test_snapshotter.rb
|
@@ -175,11 +198,13 @@ signing_key:
|
|
175
198
|
specification_version: 4
|
176
199
|
summary: TuneMyGC - optimal MRI Ruby 2.1+ Garbage Collection
|
177
200
|
test_files:
|
201
|
+
- test/delayed_job_test_backend.rb
|
178
202
|
- test/fixtures.rb
|
179
203
|
- test/helper.rb
|
180
204
|
- test/test_action_controller_interposer.rb
|
181
|
-
- test/
|
205
|
+
- test/test_active_job_interposer.rb
|
182
206
|
- test/test_agent.rb
|
207
|
+
- test/test_delayed_job_interposer.rb
|
183
208
|
- test/test_minitest_interposer.rb
|
184
209
|
- test/test_railtie.rb
|
185
210
|
- test/test_snapshotter.rb
|