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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e33b23bc2454c7112b58d3a3d248cef73dd989c0
4
- data.tar.gz: 4d9de7ed2cf2103a8a0f256d818881b4258f7f4d
3
+ metadata.gz: dee917a9ec1d9d1433370df607a9fffebf3770c2
4
+ data.tar.gz: 417022d4328e4efe72d6bffac93b57890288b5a8
5
5
  SHA512:
6
- metadata.gz: 67f321a822e3c30fae6152dab9e1fd929e79cc297f7bda4a58f05f7bb33fb25ef1182060f324e5409ffe7eb6ad17e562f767f66a0425b346a8584186988f38a3
7
- data.tar.gz: a8c8c316f64d8389c2cd00df6d498df16684264bbfd21072f2cc818d7cc642e5f3d2bc8e84c653beb1da1b188b2fac970b57f59f4829dc431f5dc377fb95b60f
6
+ metadata.gz: 57b3e42ca8b6274972d1cd2dfa47fb20d100497d0238293b45589d83a2549fbcba234d8cec0d0906060922c8ad3c2938b4eaf6ba473a3630072a5dd9936ae7e7
7
+ data.tar.gz: be9de035273d60d524df9b1e57e5e81a5dbe4e00a572d4ae75109333627db574159541aad560e1fa219665e588eda613ecea81c325a5f5b76a39f4bb93458732
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tunemygc (1.0.34)
4
+ tunemygc (1.0.35)
5
5
  certified (~> 1.0, >= 1.0.0)
6
6
 
7
7
  GEM
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
  ![tunemygc workflow diagram](https://raw.githubusercontent.com/bear-metal/tunemygc/master/assets/tunemygc-graphic2x-80dac1571cacc70d9b272bb62ae9f6df.png?token=AAABe8sM_ofiQkrCpNw7OYRbtHMLO9l5ks5UuQlYwA%3D%3D)
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 my Rails app for tuning, I'd run:
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. There's not much workflow at the moment other than applying the suggested GC configuration to your application's environment.
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 configurations
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 from https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818
119
- [TuneMyGC] export RUBY_GC_HEAP_INIT_SLOTS=382429
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
 
@@ -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 :uri, :client, :options
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
- @uri = URI("http://#{TuneMyGc::HOST}")
33
- @client = Net::HTTP.new(@uri.host, @uri.port)
34
- @client.use_ssl = (uri.port == 443)
35
- @client.read_timeout = NETWORK_TIMEOUT
36
- register if options[:email]
37
- fetch_config if options[:config]
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
@@ -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
- @subscriptions << ActiveSupport::Notifications.subscribe(/^start_processing.action_controller$/, TuneMyGc::StartRequestSubscriber.new)
42
- @subscriptions << ActiveSupport::Notifications.subscribe(/^process_action.action_controller$/, TuneMyGc::EndRequestSubscriber.new)
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
- @requests_limit ||= Integer(ENV["RUBY_GC_TUNE_REQUESTS"])
57
- @requests_processed += 1
58
- if @requests_processed == @requests_limit
55
+ @limit ||= Integer(ENV["RUBY_GC_TUNE_REQUESTS"])
56
+ @processed += 1
57
+ if @processed == @limit
59
58
  uninstall
60
- TuneMyGc.log "kamikaze after #{@requests_processed} of #{@requests_limit} requests"
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
- @jobs_limit ||= Integer(ENV["RUBY_GC_TUNE_JOBS"])
28
- @jobs_processed += 1
29
- if @jobs_processed == @jobs_limit
22
+ @limit ||= Integer(ENV["RUBY_GC_TUNE_JOBS"])
23
+ @processed += 1
24
+ if @processed == @limit
30
25
  uninstall
31
- TuneMyGc.log "kamikaze after #{@jobs_processed} of #{@jobs_limit} jobs"
26
+ TuneMyGc.log "kamikaze after #{@processed} of #{@limit} jobs"
32
27
  end
33
28
  end
34
29
  end
@@ -3,6 +3,11 @@
3
3
  module TuneMyGc
4
4
  module Spies
5
5
  class Base
6
+ def initialize
7
+ @processed = 0
8
+ @limit = nil
9
+ end
10
+
6
11
  def install
7
12
  raise NotImplementedError
8
13
  end
@@ -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
- @tests_limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
28
- @tests_processed += 1
29
- if @tests_processed == @tests_limit
22
+ @limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
23
+ @processed += 1
24
+ if @processed == @limit
30
25
  uninstall
31
- TuneMyGc.log "kamikaze after #{@tests_processed} of #{@tests_limit} tests"
26
+ TuneMyGc.log "kamikaze after #{@processed} of #{@limit} tests"
32
27
  end
33
28
  end
34
29
  end
@@ -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
- @tests_limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
32
- @tests_processed += 1
33
- if @tests_processed == @tests_limit
26
+ @limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
27
+ @processed += 1
28
+ if @processed == @limit
34
29
  uninstall
35
- TuneMyGc.log "kamikaze after #{@tests_processed} of #{@tests_limit} tests"
30
+ TuneMyGc.log "kamikaze after #{@processed} of #{@limit} tests"
36
31
  end
37
32
  end
38
33
  end
@@ -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 :uri, :client
9
+ attr_reader :client
10
10
 
11
11
  def initialize(host = TuneMyGc::HOST)
12
- @uri = URI("http://#{host}/ruby")
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(uri.path, data, TuneMyGc::HEADERS)
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
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module TuneMyGc
4
- VERSION = "1.0.34"
4
+ VERSION = "1.0.35"
5
5
  end
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.34
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-09 00:00:00.000000000 Z
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