tunemygc 1.0.34 → 1.0.35

Sign up to get free protection for your applications and to get access to all the features.
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