tunemygc 1.0.6 → 1.0.7
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/.travis.yml +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +16 -6
- data/lib/tunemygc/agent.rb +8 -0
- data/lib/tunemygc/interposer.rb +3 -3
- data/lib/tunemygc/spies.rb +8 -0
- data/lib/tunemygc/spies/minitest.rb +74 -0
- data/lib/tunemygc/syncer.rb +1 -1
- data/lib/tunemygc/version.rb +1 -1
- data/test/helper.rb +16 -1
- data/test/{test_interposer.rb → test_action_controller_interposer.rb} +14 -3
- data/test/test_agent.rb +8 -0
- data/test/test_minitest_interposer.rb +79 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 759855e794865c4d3a4dd7fb6eeee7789c07283d
|
4
|
+
data.tar.gz: 51e021f692c505cc6c102bac6287d17214930d9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73b470f53ef683edc2294adc3738ba8e4a329efbcfc127b18f7a2e51bf1777efc4b4fb7726108969dcc6998560b5c6a1a69c14ed93984dc150be25839be7151b
|
7
|
+
data.tar.gz: eefd05ae81273e370dd01d1087f278d13f4ed4350c3d6d8357fa4c1e42866ffac082f8c364a9d28addfc6860f4b783ae057914394f4059a70a649b29fbe9da3c
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -20,6 +20,8 @@ The Ruby garbage collector has been flagged as the crux of Ruby performance and
|
|
20
20
|
|
21
21
|
We used [Discourse](http://www.discourse.org) as our primary test harness as it's representative of most Rails applications and has been instrumental in asserting RGenC developments on Rails as well.
|
22
22
|
|
23
|
+
[Discourse](http://www.discourse.org) throughput: [GC defaults](https://tunemygc.com/configs/c5214cfa00b3bf429badd2161c4b6a08) VS TuneMyGc [suggestions](https://tunemygc.com/configs/e129791f94159a8c75bef3a636c05798)
|
24
|
+
|
23
25
|

|
24
26
|
|
25
27
|
## Installing
|
@@ -42,7 +44,7 @@ Has not been tested at all.
|
|
42
44
|
There isn't much setup other than adding the gem to your Gemfile and running a single command from your application root to register your application with the `https://tunemygc.com` service:
|
43
45
|
|
44
46
|
``` sh
|
45
|
-
|
47
|
+
$ bundle exec tunemygc -r lourens@bearmetal.eu
|
46
48
|
Application registered. Use RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 in your environment.
|
47
49
|
```
|
48
50
|
|
@@ -57,7 +59,7 @@ RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails
|
|
57
59
|
The CLI interface supports retrieving configuration options for your application as well.
|
58
60
|
|
59
61
|
``` sh
|
60
|
-
|
62
|
+
$ bundle exec tunemygc
|
61
63
|
Usage: tunemygc [options]
|
62
64
|
-r, --register EMAIL Register this Rails app with the https://tunemygc.com service
|
63
65
|
-c, --config TOKEN Fetch the last known config for a given Rails app
|
@@ -75,13 +77,13 @@ We fully embrace and encourage [12 factor](http://12factor.net) conventions and
|
|
75
77
|
This application specific token is required for GC instrumentation. You can generate one from the CLI interface by registering for the service with a valid email address:
|
76
78
|
|
77
79
|
``` sh
|
78
|
-
|
80
|
+
$ bundle exec tunemygc -r lourens@bearmetal.eu
|
79
81
|
Application registered. Use RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 in your environment.
|
80
82
|
```
|
81
83
|
|
82
84
|
* `RUBY_GC_TUNE=1`
|
83
85
|
|
84
|
-
Enables the interposer for taking a few lightweight snapshots and submitting them to `tunemygc.com`. Without this environment variable set, it won't interpose itself.
|
86
|
+
Enables the interposer for taking a few lightweight snapshots of Rails requests and submitting them to `tunemygc.com`. Without this environment variable set, it won't interpose itself.
|
85
87
|
|
86
88
|
For the above command sequences, to sample my Rails app for tuning, I'd run:
|
87
89
|
|
@@ -91,9 +93,17 @@ RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails
|
|
91
93
|
|
92
94
|
#### Advanced
|
93
95
|
|
96
|
+
* `RUBY_GC_SPY=action_controller` (Spy on the GC for this type of processing. Either `action_controller` or `minitest`)
|
97
|
+
|
98
|
+
Defines what type of processing you would like to sample for GC activity. An Action Controller spy is the default, but [minitest](https://github.com/seattlerb/minitest) is also supported as an experimental feature.
|
99
|
+
|
94
100
|
* `RUBY_GC_TUNE_REQUESTS=x` (a numeric value eg. `200`)
|
95
101
|
|
96
|
-
Controls the interposer lifetime for sampling requests. It will enable itself, then remove request instrumentation after the specified number of requests. A good minimum ballpark sample set would be 200.
|
102
|
+
Controls the interposer lifetime for sampling Rails requests. It will enable itself, then remove request instrumentation after the specified number of requests. A good minimum ballpark sample set would be 200.
|
103
|
+
|
104
|
+
* `RUBY_GC_TUNE_TESTS=x` (a numeric value eg. `200`)
|
105
|
+
|
106
|
+
Controls the interposer lifetime for sampling a [minitest](https://github.com/seattlerb/minitest) based test suite. It will enable itself, then remove request instrumentation after the specified number of tests has been run. A good minimum ballpark sample set would be 200.
|
97
107
|
|
98
108
|
## How do I use this?
|
99
109
|
|
@@ -122,7 +132,7 @@ An instrumented process dumps a reccommended config to the Rails logger.
|
|
122
132
|
We're still in the process of building tools and a launcher shim around this. You can also retrieve the last known configuration for you app via the CLI interface:
|
123
133
|
|
124
134
|
``` sh
|
125
|
-
|
135
|
+
$ bundle exec tunemygc -c 3b8796e5627f97ec760f000d55d9b3f5
|
126
136
|
=== Suggested GC configuration:
|
127
137
|
|
128
138
|
export RUBY_GC_HEAP_INIT_SLOTS=382429
|
data/lib/tunemygc/agent.rb
CHANGED
@@ -22,6 +22,14 @@ module TuneMyGc
|
|
22
22
|
logger.info "[TuneMyGC] #{message}"
|
23
23
|
end
|
24
24
|
|
25
|
+
def spy
|
26
|
+
if ENV['RUBY_GC_SPY']
|
27
|
+
ENV['RUBY_GC_SPY'].classify
|
28
|
+
else
|
29
|
+
:ActionController
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
25
33
|
def reccommendations
|
26
34
|
MUTEX.synchronize do
|
27
35
|
require "tunemygc/syncer"
|
data/lib/tunemygc/interposer.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'active_support'
|
4
|
-
require 'tunemygc/spies
|
4
|
+
require 'tunemygc/spies'
|
5
5
|
|
6
6
|
module TuneMyGc
|
7
7
|
class Interposer
|
8
8
|
attr_reader :spy
|
9
9
|
attr_accessor :installed
|
10
10
|
|
11
|
-
def initialize
|
11
|
+
def initialize(spy = TuneMyGc.spy)
|
12
12
|
reset
|
13
|
+
@spy = TuneMyGc::Spies.const_get(spy).new
|
13
14
|
end
|
14
15
|
|
15
16
|
def on_initialized
|
@@ -54,7 +55,6 @@ module TuneMyGc
|
|
54
55
|
private
|
55
56
|
def reset
|
56
57
|
@installed = false
|
57
|
-
@spy = TuneMyGc::Spies::ActionController.new
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'minitest'
|
4
|
+
|
5
|
+
module TuneMyGc
|
6
|
+
module Spies
|
7
|
+
class Minitest
|
8
|
+
def initialize
|
9
|
+
@tests_processed = 0
|
10
|
+
@tests_limit = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def install
|
14
|
+
MiniTest::Unit::TestCase.__send__(:include, hooks_module)
|
15
|
+
TuneMyGc.log "hooked: minitest"
|
16
|
+
end
|
17
|
+
|
18
|
+
def uninstall
|
19
|
+
TuneMyGc.uninstall_gc_tracepoint
|
20
|
+
TuneMyGc.log "uninstalled GC tracepoint"
|
21
|
+
MiniTest::Unit::TestCase.__send__(:include, disabled_hooks_module)
|
22
|
+
TuneMyGc.log "uninstalled minitest spy"
|
23
|
+
end
|
24
|
+
|
25
|
+
def check_uninstall
|
26
|
+
if ENV["RUBY_GC_TUNE_TESTS"]
|
27
|
+
@tests_limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
|
28
|
+
@tests_processed += 1
|
29
|
+
if @tests_processed == @tests_limit
|
30
|
+
uninstall
|
31
|
+
TuneMyGc.log "kamikaze after #{@tests_processed} of #{@tests_limit} tests"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def hooks_module
|
37
|
+
Module.new do
|
38
|
+
def before_setup
|
39
|
+
tunemygc_before_setup
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def after_teardown
|
44
|
+
super
|
45
|
+
tunemygc_after_teardown
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def tunemygc_before_setup
|
50
|
+
TuneMyGc.snapshot(:TEST_PROCESSING_STARTED)
|
51
|
+
end
|
52
|
+
|
53
|
+
def tunemygc_after_teardown
|
54
|
+
TuneMyGc.snapshot(:TEST_PROCESSING_ENDED)
|
55
|
+
TuneMyGc.interposer.check_uninstall
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def disabled_hooks_module
|
61
|
+
Module.new do
|
62
|
+
private
|
63
|
+
def tunemygc_before_setup
|
64
|
+
# noop
|
65
|
+
end
|
66
|
+
|
67
|
+
def tunemygc_after_teardown
|
68
|
+
# noop
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/tunemygc/syncer.rb
CHANGED
data/lib/tunemygc/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -23,8 +23,23 @@ class TuneMyGcTestCase < Minitest::Test
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def process_tunemygc_request(path = '/test')
|
27
27
|
ActiveSupport::Notifications.instrument('start_processing.action_controller', path: path) {}
|
28
28
|
ActiveSupport::Notifications.instrument('process_action.action_controller', path: path) {}
|
29
29
|
end
|
30
|
+
|
31
|
+
def run_tunemygc_test
|
32
|
+
MinitestSandboxTest.new("test_minitest_spy").run
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# for Minitest spy
|
37
|
+
class MinitestSandboxTest < MiniTest::Unit::TestCase
|
38
|
+
def setup
|
39
|
+
@value = 123
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_minitest_spy
|
43
|
+
assert_equal 123, @value
|
44
|
+
end
|
30
45
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require File.join(File.dirname(__FILE__), 'helper')
|
4
4
|
|
5
|
-
class
|
5
|
+
class TestActionControllerInterposer < TuneMyGcTestCase
|
6
6
|
def setup
|
7
7
|
TuneMyGc.interposer.uninstall
|
8
8
|
end
|
@@ -58,10 +58,21 @@ class TestInterposer < TuneMyGcTestCase
|
|
58
58
|
|
59
59
|
ENV["RUBY_GC_TUNE_REQUESTS"] = "2"
|
60
60
|
|
61
|
-
|
61
|
+
process_tunemygc_request
|
62
62
|
assert_equal 2, interposer.spy.subscriptions.size
|
63
|
-
|
63
|
+
process_tunemygc_request
|
64
64
|
assert_equal 0, interposer.spy.subscriptions.size
|
65
|
+
|
66
|
+
stages = []
|
67
|
+
|
68
|
+
while !TuneMyGc.snapshotter.empty?
|
69
|
+
stages << TuneMyGc.snapshotter.deq
|
70
|
+
end
|
71
|
+
|
72
|
+
cycles = [:REQUEST_PROCESSING_STARTED]
|
73
|
+
|
74
|
+
assert stages.any?{|s| cycles.include?(s[3]) }
|
75
|
+
|
65
76
|
interposer.uninstall
|
66
77
|
ensure
|
67
78
|
ENV.delete("RUBY_GC_TUNE_REQUESTS")
|
data/test/test_agent.rb
CHANGED
@@ -11,6 +11,14 @@ class TestAgent < TuneMyGcTestCase
|
|
11
11
|
assert_instance_of TuneMyGc::Snapshotter, TuneMyGc.snapshotter
|
12
12
|
end
|
13
13
|
|
14
|
+
def test_spy
|
15
|
+
assert_equal :ActionController, TuneMyGc.spy
|
16
|
+
ENV['RUBY_GC_SPY'] = "minitest"
|
17
|
+
assert_equal 'Minitest', TuneMyGc.spy
|
18
|
+
ensure
|
19
|
+
ENV.delete('RUBY_GC_SPY')
|
20
|
+
end
|
21
|
+
|
14
22
|
def test_log
|
15
23
|
out, err = capture_io do
|
16
24
|
TuneMyGc.logger = Logger.new($stdout)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
4
|
+
|
5
|
+
class TestMinitestInterposer < TuneMyGcTestCase
|
6
|
+
def setup
|
7
|
+
TuneMyGc.interposer.uninstall
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new(:ActionController)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_init
|
15
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new(:Minitest)
|
16
|
+
interposer = TuneMyGc.interposer
|
17
|
+
assert !interposer.installed
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_install_uninstall
|
21
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new(:Minitest)
|
22
|
+
interposer = TuneMyGc.interposer
|
23
|
+
interposer.install
|
24
|
+
interposer.on_initialized
|
25
|
+
assert interposer.installed
|
26
|
+
assert_nil interposer.install
|
27
|
+
|
28
|
+
interposer.uninstall
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_gc_hooks
|
32
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new(:Minitest)
|
33
|
+
interposer = TuneMyGc.interposer
|
34
|
+
interposer.install
|
35
|
+
TuneMyGc.interposer.on_initialized
|
36
|
+
|
37
|
+
GC.start(full_mark: true, immediate_sweep: false)
|
38
|
+
GC.start(full_mark: true, immediate_sweep: true)
|
39
|
+
|
40
|
+
stages = []
|
41
|
+
|
42
|
+
while !TuneMyGc.snapshotter.empty?
|
43
|
+
stages << TuneMyGc.snapshotter.deq
|
44
|
+
end
|
45
|
+
|
46
|
+
# Account for incremental GC on 2.2
|
47
|
+
cycles = [:GC_CYCLE_STARTED, :GC_CYCLE_ENTERED]
|
48
|
+
|
49
|
+
assert stages.any?{|s| cycles.include?(s[3]) }
|
50
|
+
|
51
|
+
interposer.uninstall
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_tests_limit
|
55
|
+
TuneMyGc.interposer = TuneMyGc::Interposer.new(:Minitest)
|
56
|
+
interposer = TuneMyGc.interposer
|
57
|
+
interposer.install
|
58
|
+
TuneMyGc.interposer.on_initialized
|
59
|
+
|
60
|
+
ENV["RUBY_GC_TUNE_TESTS"] = "2"
|
61
|
+
|
62
|
+
run_tunemygc_test
|
63
|
+
run_tunemygc_test
|
64
|
+
|
65
|
+
stages = []
|
66
|
+
|
67
|
+
while !TuneMyGc.snapshotter.empty?
|
68
|
+
stages << TuneMyGc.snapshotter.deq
|
69
|
+
end
|
70
|
+
|
71
|
+
cycles = [:TEST_PROCESSING_STARTED]
|
72
|
+
|
73
|
+
assert stages.any?{|s| cycles.include?(s[3]) }
|
74
|
+
|
75
|
+
interposer.uninstall
|
76
|
+
ensure
|
77
|
+
ENV.delete("RUBY_GC_TUNE_TESTS")
|
78
|
+
end
|
79
|
+
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.7
|
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-02-
|
11
|
+
date: 2015-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -129,14 +129,17 @@ files:
|
|
129
129
|
- lib/tunemygc/railtie.rb
|
130
130
|
- lib/tunemygc/request_subscriber.rb
|
131
131
|
- lib/tunemygc/snapshotter.rb
|
132
|
+
- lib/tunemygc/spies.rb
|
132
133
|
- lib/tunemygc/spies/action_controller.rb
|
134
|
+
- lib/tunemygc/spies/minitest.rb
|
133
135
|
- lib/tunemygc/subscriber.rb
|
134
136
|
- lib/tunemygc/syncer.rb
|
135
137
|
- lib/tunemygc/version.rb
|
136
138
|
- test/fixtures.rb
|
137
139
|
- test/helper.rb
|
140
|
+
- test/test_action_controller_interposer.rb
|
138
141
|
- test/test_agent.rb
|
139
|
-
- test/
|
142
|
+
- test/test_minitest_interposer.rb
|
140
143
|
- test/test_railtie.rb
|
141
144
|
- test/test_snapshotter.rb
|
142
145
|
- test/test_syncer.rb
|
@@ -186,8 +189,9 @@ summary: TuneMyGC - optimal MRI Ruby 2.1+ Garbage Collection
|
|
186
189
|
test_files:
|
187
190
|
- test/fixtures.rb
|
188
191
|
- test/helper.rb
|
192
|
+
- test/test_action_controller_interposer.rb
|
189
193
|
- test/test_agent.rb
|
190
|
-
- test/
|
194
|
+
- test/test_minitest_interposer.rb
|
191
195
|
- test/test_railtie.rb
|
192
196
|
- test/test_snapshotter.rb
|
193
197
|
- test/test_syncer.rb
|