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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9bc21ec0d45e156bf1a8646f766c5e2faef5b50
4
- data.tar.gz: 575e3a4b82a1eb2fca4c7f4dd1c66e8763909a8e
3
+ metadata.gz: c7729fb0e74aeaa4d3015d0e2204c4aaf07c140c
4
+ data.tar.gz: 73ba3d4ea9b191a881f69eb32477d7fb055b512d
5
5
  SHA512:
6
- metadata.gz: c2cd02a42b1e7f8af391cb2146d803cb006152e3b7288ebcac0ae26920dd1c045b7b0165d51100b4a220320a02f75cd78207c59ec988e7d0f4a56269583eebff
7
- data.tar.gz: 9c53a726d80c244e7db4cb7386091aaa7fe2931e2757618c39e93910b337f7494dea7d81f9097c743fc617181cc55b9a819e4ee2e143f80bdc68d1131f2e8910
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.53)
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
@@ -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
- spy :Minitest, 'minitest'
13
- spy :ActiveJob, 'active_job'
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|
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module TuneMyGc
4
- VERSION = "1.0.55"
4
+ VERSION = "1.0.56"
5
5
  end
@@ -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
@@ -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.55
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-15 00:00:00.000000000 Z
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/test_activejob_interposer.rb
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/test_activejob_interposer.rb
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