tunemygc 1.0.34 → 1.0.35
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 +1 -1
- data/README.md +29 -18
- data/lib/tunemygc/agent.rb +0 -2
- data/lib/tunemygc/cli.rb +9 -7
- data/lib/tunemygc/network.rb +8 -0
- data/lib/tunemygc/spies/action_controller.rb +12 -8
- data/lib/tunemygc/spies/active_job.rb +4 -9
- data/lib/tunemygc/spies/base.rb +5 -0
- data/lib/tunemygc/spies/minitest.rb +4 -9
- data/lib/tunemygc/spies/rspec.rb +4 -9
- data/lib/tunemygc/syncer.rb +3 -10
- data/lib/tunemygc/version.rb +1 -1
- data/test/test_syncer.rb +0 -6
- metadata +2 -3
- data/lib/tunemygc/configurator.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dee917a9ec1d9d1433370df607a9fffebf3770c2
|
4
|
+
data.tar.gz: 417022d4328e4efe72d6bffac93b57890288b5a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57b3e42ca8b6274972d1cd2dfa47fb20d100497d0238293b45589d83a2549fbcba234d8cec0d0906060922c8ad3c2938b4eaf6ba473a3630072a5dd9936ae7e7
|
7
|
+
data.tar.gz: be9de035273d60d524df9b1e57e5e81a5dbe4e00a572d4ae75109333627db574159541aad560e1fa219665e588eda613ecea81c325a5f5b76a39f4bb93458732
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -8,6 +8,8 @@ The Ruby garbage collector has been flagged as the crux of Ruby performance and
|
|
8
8
|
|
9
9
|

|
10
10
|
|
11
|
+
We also recently [blogged](http://bearmetal.eu/theden/2015-02-20-rails-garbage-collection-tuning-approaches) about how the product works.
|
12
|
+
|
11
13
|
## Benefits
|
12
14
|
|
13
15
|
* Faster boot times
|
@@ -33,6 +35,7 @@ Add to your Gemfile and run `bundle install`
|
|
33
35
|
``` sh
|
34
36
|
gem 'tunemygc'
|
35
37
|
```
|
38
|
+
|
36
39
|
This gem linterposes itself into the application and piggy backs off the new GC events in Ruby 2.x for introspection. Tuning recommendations are handled through a web service at `https://tunemygc.com`. You will need MRI Ruby `2.1`, or later. [Rails](http://www.rubyonrails.org) applications, background jobs, tests and any proprietary Ruby scripts and frameworks are supported.
|
37
40
|
|
38
41
|
## Getting started
|
@@ -52,6 +55,14 @@ For the above command sequences, to sample your app or script for tuning, run (i
|
|
52
55
|
RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails s
|
53
56
|
```
|
54
57
|
|
58
|
+
And after some profiling requests, when the process terminates, you can visit the given report URL for a config recommendation and some further insights:
|
59
|
+
|
60
|
+
``` sh
|
61
|
+
[TuneMyGC, pid: 70160] Syncing 688 snapshots
|
62
|
+
[TuneMyGC, pid: 70160] ==== Recommended GC configs for ActionController
|
63
|
+
[TuneMyGC, pid: 70160] Please visit https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818 to view your configuration and other Garbage Collector insights
|
64
|
+
```
|
65
|
+
|
55
66
|
The CLI interface supports retrieving configuration options for your application as well.
|
56
67
|
|
57
68
|
``` sh
|
@@ -81,12 +92,20 @@ Application registered. Use RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 in yo
|
|
81
92
|
|
82
93
|
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.
|
83
94
|
|
84
|
-
For the above command sequences, to sample
|
95
|
+
For the above command sequences, to sample a Rails app for tuning, run:
|
85
96
|
|
86
97
|
``` sh
|
87
98
|
RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails s
|
88
99
|
```
|
89
100
|
|
101
|
+
And after some profiling requests, when the process terminates, you can visit the given report URL for a config recommendation and some further insights:
|
102
|
+
|
103
|
+
``` sh
|
104
|
+
[TuneMyGC, pid: 70160] Syncing 688 snapshots
|
105
|
+
[TuneMyGC, pid: 70160] ==== Recommended GC configs for ActionController
|
106
|
+
[TuneMyGC, pid: 70160] Please visit https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818 to view your configuration and other Garbage Collector insights
|
107
|
+
```
|
108
|
+
|
90
109
|
#### Advanced
|
91
110
|
|
92
111
|
* `RUBY_GC_SPY=action_controller` (Spy on the GC for this type of processing. `action_controller`, `active_job`, `minitest` or `rspec` are supported)
|
@@ -107,26 +126,16 @@ Controls the interposer lifetime for sampling a [minitest](https://github.com/se
|
|
107
126
|
|
108
127
|
## How do I use this?
|
109
128
|
|
110
|
-
This gem is only a lightweight agent and designed to not get in your way.
|
129
|
+
This gem is only a lightweight agent and designed to not get in your way. It samples your application during runtime, syncs data with our web service when it terminates and we provide a report URL where you can view a suggested GC configuration and additional tips and insights.
|
111
130
|
|
112
|
-
#### Interpreting
|
131
|
+
#### Interpreting results
|
113
132
|
|
114
|
-
An instrumented process dumps a reccommended config to the Rails logger.
|
133
|
+
An instrumented process dumps a report URL with a reccommended config to the Rails logger.
|
115
134
|
|
116
135
|
``` sh
|
117
|
-
[TuneMyGC] Syncing 688 snapshots
|
118
|
-
[TuneMyGC] ==== Recommended GC configs
|
119
|
-
[TuneMyGC]
|
120
|
-
[TuneMyGC] export RUBY_GC_HEAP_FREE_SLOTS=603850
|
121
|
-
[TuneMyGC] export RUBY_GC_HEAP_GROWTH_FACTOR=1.2
|
122
|
-
[TuneMyGC] export RUBY_GC_HEAP_GROWTH_MAX_SLOTS=301925
|
123
|
-
[TuneMyGC] export RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=2.0
|
124
|
-
[TuneMyGC] export RUBY_GC_MALLOC_LIMIT=35818030
|
125
|
-
[TuneMyGC] export RUBY_GC_MALLOC_LIMIT_MAX=42981636
|
126
|
-
[TuneMyGC] export RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.32
|
127
|
-
[TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT=32782669
|
128
|
-
[TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT_MAX=49174003.5
|
129
|
-
[TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
|
136
|
+
[TuneMyGC, pid: 70160] Syncing 688 snapshots
|
137
|
+
[TuneMyGC, pid: 70160] ==== Recommended GC configs for ActionController
|
138
|
+
[TuneMyGC, pid: 70160] Please visit https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818 to view your configuration and other Garbage Collector insights
|
130
139
|
```
|
131
140
|
|
132
141
|
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:
|
@@ -148,9 +157,11 @@ export RUBY_GC_OLDMALLOC_LIMIT_MAX=49174003.5
|
|
148
157
|
export RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
|
149
158
|
```
|
150
159
|
|
160
|
+
We're busy working on adding tips on the report URLs for some common problem contexts.
|
161
|
+
|
151
162
|
#### Heroku and 12 factor
|
152
163
|
|
153
|
-
We have a [Heroku](http://www.heroku.com) addon in Alpha testing and the Ruby GC lends itself well to tuning through 12 factor principles as it's designed around environment variables.
|
164
|
+
We have a [Heroku](http://www.heroku.com) addon in Alpha testing and the Ruby GC lends itself well to tuning through [12 factor](http://12factor.net) principles as it's designed around environment variables.
|
154
165
|
|
155
166
|
## Security and privacy concerns
|
156
167
|
|
data/lib/tunemygc/agent.rb
CHANGED
@@ -48,8 +48,6 @@ module TuneMyGc
|
|
48
48
|
require "tunemygc/syncer"
|
49
49
|
syncer = TuneMyGc::Syncer.new
|
50
50
|
config = syncer.sync(snapshotter)
|
51
|
-
require "tunemygc/configurator"
|
52
|
-
TuneMyGc::Configurator.new(config).configure
|
53
51
|
end
|
54
52
|
rescue Exception => e
|
55
53
|
log "Config reccommendation error (#{e.message})"
|
data/lib/tunemygc/cli.rb
CHANGED
@@ -5,7 +5,7 @@ require 'optparse'
|
|
5
5
|
|
6
6
|
module TuneMyGc
|
7
7
|
class CLI
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :client, :options
|
9
9
|
|
10
10
|
def self.start(args)
|
11
11
|
args = ["-h"] if args.empty?
|
@@ -29,12 +29,14 @@ module TuneMyGc
|
|
29
29
|
|
30
30
|
def initialize(options)
|
31
31
|
@options = options
|
32
|
-
@
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
@client = TuneMyGc.http_client
|
33
|
+
if options[:email]
|
34
|
+
register
|
35
|
+
elsif options[:config]
|
36
|
+
fetch_config
|
37
|
+
else
|
38
|
+
raise ArgumentError, "Invalid CLI argument: you can either register or retrieve your last known GC config"
|
39
|
+
end
|
38
40
|
end
|
39
41
|
|
40
42
|
def register
|
data/lib/tunemygc/network.rb
CHANGED
@@ -6,4 +6,12 @@ require 'timeout'
|
|
6
6
|
|
7
7
|
module TuneMyGc
|
8
8
|
NETWORK_TIMEOUT = 30 #seconds
|
9
|
+
|
10
|
+
def self.http_client
|
11
|
+
uri = URI("https://#{TuneMyGc::HOST}")
|
12
|
+
client = Net::HTTP.new(uri.host, uri.port)
|
13
|
+
client.use_ssl = true
|
14
|
+
client.read_timeout = NETWORK_TIMEOUT
|
15
|
+
client
|
16
|
+
end
|
9
17
|
end
|
@@ -32,14 +32,13 @@ module TuneMyGc
|
|
32
32
|
attr_reader :subscriptions
|
33
33
|
|
34
34
|
def initialize
|
35
|
+
super
|
35
36
|
@subscriptions = []
|
36
|
-
@requests_processed = 0
|
37
|
-
@requests_limit = nil
|
38
37
|
end
|
39
38
|
|
40
39
|
def install
|
41
|
-
|
42
|
-
|
40
|
+
subscription(/^start_processing.action_controller$/, TuneMyGc::StartRequestSubscriber.new)
|
41
|
+
subscription(/^process_action.action_controller$/, TuneMyGc::EndRequestSubscriber.new)
|
43
42
|
TuneMyGc.log "hooked: action_controller"
|
44
43
|
end
|
45
44
|
|
@@ -53,14 +52,19 @@ module TuneMyGc
|
|
53
52
|
|
54
53
|
def check_uninstall
|
55
54
|
if ENV["RUBY_GC_TUNE_REQUESTS"]
|
56
|
-
@
|
57
|
-
@
|
58
|
-
if @
|
55
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_REQUESTS"])
|
56
|
+
@processed += 1
|
57
|
+
if @processed == @limit
|
59
58
|
uninstall
|
60
|
-
TuneMyGc.log "kamikaze after #{@
|
59
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} requests"
|
61
60
|
end
|
62
61
|
end
|
63
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def subscription(pattern, handler)
|
66
|
+
@subscriptions << ActiveSupport::Notifications.subscribe(pattern, handler)
|
67
|
+
end
|
64
68
|
end
|
65
69
|
end
|
66
70
|
end
|
@@ -5,11 +5,6 @@ require 'active_job'
|
|
5
5
|
module TuneMyGc
|
6
6
|
module Spies
|
7
7
|
class ActiveJob < TuneMyGc::Spies::Base
|
8
|
-
def initialize
|
9
|
-
@jobs_processed = 0
|
10
|
-
@jobs_limit = nil
|
11
|
-
end
|
12
|
-
|
13
8
|
def install
|
14
9
|
::ActiveJob::Base.__send__(:include, hooks_module)
|
15
10
|
TuneMyGc.log "hooked: active_job"
|
@@ -24,11 +19,11 @@ module TuneMyGc
|
|
24
19
|
|
25
20
|
def check_uninstall
|
26
21
|
if ENV["RUBY_GC_TUNE_JOBS"]
|
27
|
-
@
|
28
|
-
@
|
29
|
-
if @
|
22
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_JOBS"])
|
23
|
+
@processed += 1
|
24
|
+
if @processed == @limit
|
30
25
|
uninstall
|
31
|
-
TuneMyGc.log "kamikaze after #{@
|
26
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} jobs"
|
32
27
|
end
|
33
28
|
end
|
34
29
|
end
|
data/lib/tunemygc/spies/base.rb
CHANGED
@@ -5,11 +5,6 @@ require 'minitest'
|
|
5
5
|
module TuneMyGc
|
6
6
|
module Spies
|
7
7
|
class Minitest < TuneMyGc::Spies::Base
|
8
|
-
def initialize
|
9
|
-
@tests_processed = 0
|
10
|
-
@tests_limit = nil
|
11
|
-
end
|
12
|
-
|
13
8
|
def install
|
14
9
|
MiniTest::Unit::TestCase.__send__(:include, hooks_module)
|
15
10
|
TuneMyGc.log "hooked: minitest"
|
@@ -24,11 +19,11 @@ module TuneMyGc
|
|
24
19
|
|
25
20
|
def check_uninstall
|
26
21
|
if ENV["RUBY_GC_TUNE_TESTS"]
|
27
|
-
@
|
28
|
-
@
|
29
|
-
if @
|
22
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
|
23
|
+
@processed += 1
|
24
|
+
if @processed == @limit
|
30
25
|
uninstall
|
31
|
-
TuneMyGc.log "kamikaze after #{@
|
26
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} tests"
|
32
27
|
end
|
33
28
|
end
|
34
29
|
end
|
data/lib/tunemygc/spies/rspec.rb
CHANGED
@@ -9,11 +9,6 @@ end
|
|
9
9
|
module TuneMyGc
|
10
10
|
module Spies
|
11
11
|
class Rspec < TuneMyGc::Spies::Base
|
12
|
-
def initialize
|
13
|
-
@tests_processed = 0
|
14
|
-
@tests_limit = nil
|
15
|
-
end
|
16
|
-
|
17
12
|
def install
|
18
13
|
RSpec::Core.__send__(:include, hooks_module)
|
19
14
|
TuneMyGc.log "hooked: rspec"
|
@@ -28,11 +23,11 @@ module TuneMyGc
|
|
28
23
|
|
29
24
|
def check_uninstall
|
30
25
|
if ENV["RUBY_GC_TUNE_TESTS"]
|
31
|
-
@
|
32
|
-
@
|
33
|
-
if @
|
26
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
|
27
|
+
@processed += 1
|
28
|
+
if @processed == @limit
|
34
29
|
uninstall
|
35
|
-
TuneMyGc.log "kamikaze after #{@
|
30
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} tests"
|
36
31
|
end
|
37
32
|
end
|
38
33
|
end
|
data/lib/tunemygc/syncer.rb
CHANGED
@@ -6,13 +6,10 @@ module TuneMyGc
|
|
6
6
|
class Syncer
|
7
7
|
ENVIRONMENT = [ENV['RUBY_GC_TOKEN'], RUBY_VERSION, TuneMyGc.rails_version, ENV.select {|k,v| k =~ /RUBY_GC_/ }, TuneMyGc::VERSION, GC::OPTS, GC::INTERNAL_CONSTANTS].freeze
|
8
8
|
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :client
|
10
10
|
|
11
11
|
def initialize(host = TuneMyGc::HOST)
|
12
|
-
@
|
13
|
-
@client = Net::HTTP.new(@uri.host, @uri.port)
|
14
|
-
@client.use_ssl = (uri.port == 443)
|
15
|
-
@client.read_timeout = NETWORK_TIMEOUT
|
12
|
+
@client = TuneMyGc.http_client
|
16
13
|
end
|
17
14
|
|
18
15
|
def sync(snapshotter)
|
@@ -58,7 +55,7 @@ module TuneMyGc
|
|
58
55
|
payload << snapshot
|
59
56
|
end
|
60
57
|
data = ActiveSupport::JSON.encode(payload)
|
61
|
-
response = client.post(
|
58
|
+
response = client.post('/ruby', data, TuneMyGc::HEADERS)
|
62
59
|
snapshotter.unit_of_work = false
|
63
60
|
if Net::HTTPNotFound === response
|
64
61
|
TuneMyGc.log "Invalid application token. Please generate one with 'bundle exec tunemygc <a_valid_email_address>' and set the RUBY_GC_TOKEN environment variable"
|
@@ -94,11 +91,7 @@ module TuneMyGc
|
|
94
91
|
|
95
92
|
def process_config_callback(response)
|
96
93
|
report_url = response.body.gsub(/\.json$/, '')
|
97
|
-
config = client.get(URI(response.body).path)
|
98
|
-
ActiveSupport::JSON.decode(config.body).merge('report' => report_url)
|
99
|
-
rescue Exception => e
|
100
94
|
TuneMyGc.log "Please visit #{report_url} to view your configuration and other Garbage Collector insights"
|
101
|
-
return false
|
102
95
|
end
|
103
96
|
end
|
104
97
|
end
|
data/lib/tunemygc/version.rb
CHANGED
data/test/test_syncer.rb
CHANGED
@@ -3,12 +3,6 @@
|
|
3
3
|
require File.join(File.dirname(__FILE__), 'helper')
|
4
4
|
|
5
5
|
class TestSyncer < TuneMyGcTestCase
|
6
|
-
def test_uri
|
7
|
-
syncer = TuneMyGc::Syncer.new
|
8
|
-
assert_equal "tunemygc.com", syncer.uri.host
|
9
|
-
assert_equal 443, syncer.uri.port
|
10
|
-
end
|
11
|
-
|
12
6
|
def test_client
|
13
7
|
syncer = TuneMyGc::Syncer.new
|
14
8
|
assert_instance_of Net::HTTP, syncer.client
|
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.35
|
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-03-
|
11
|
+
date: 2015-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: certified
|
@@ -139,7 +139,6 @@ files:
|
|
139
139
|
- lib/tunemygc.rb
|
140
140
|
- lib/tunemygc/agent.rb
|
141
141
|
- lib/tunemygc/cli.rb
|
142
|
-
- lib/tunemygc/configurator.rb
|
143
142
|
- lib/tunemygc/interposer.rb
|
144
143
|
- lib/tunemygc/network.rb
|
145
144
|
- lib/tunemygc/railtie.rb
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TuneMyGc
|
4
|
-
class Configurator
|
5
|
-
attr_reader :config
|
6
|
-
|
7
|
-
def initialize(config)
|
8
|
-
@config = config
|
9
|
-
end
|
10
|
-
|
11
|
-
def configure
|
12
|
-
if Hash === config && !config.empty?
|
13
|
-
TuneMyGc.log "==== Recommended GC configs for #{TuneMyGCc::Spies.current}: #{config.delete("report")}"
|
14
|
-
write_env("Speed")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
def write_env(strategy)
|
20
|
-
config.delete(strategy).each do |var,val|
|
21
|
-
TuneMyGc.log "export #{var}=#{val}"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|