autotuner 1.0.1 → 1.1.0
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/.devcontainer/devcontainer.json +25 -0
- data/.ruby-version +1 -1
- data/Gemfile +3 -3
- data/Gemfile.lock +34 -29
- data/README.md +13 -1
- data/autotuner.gemspec +33 -0
- data/lib/autotuner/data_structure/data_points.rb +1 -1
- data/lib/autotuner/heuristic/base.rb +1 -3
- data/lib/autotuner/heuristic/gc_compact.rb +10 -4
- data/lib/autotuner/heuristic/heap_size_warmup.rb +7 -3
- data/lib/autotuner/heuristic/malloc.rb +1 -2
- data/lib/autotuner/heuristic/oldmalloc.rb +1 -2
- data/lib/autotuner/heuristic/remembered_wb_unprotected_objects.rb +1 -2
- data/lib/autotuner/heuristics.rb +3 -3
- data/lib/autotuner/report/base.rb +3 -2
- data/lib/autotuner/report/multiple_environment_variables.rb +3 -3
- data/lib/autotuner/report/single_environment_variable.rb +2 -2
- data/lib/autotuner/request_collector.rb +14 -6
- data/lib/autotuner/version.rb +1 -1
- metadata +5 -7
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2110ae589a151476ac745ec4767d13e3146c890df830108745dc077c64f79f50
         | 
| 4 | 
            +
              data.tar.gz: cea9ce8c687ae32214f41b65466e110abdab8bb00e1aab0596c9d787b510b496
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 75e382f22166a16159065717da0bdff1e428986c6367d3c6598978bb7354ebf25074cb2b4a335ff5a1e252b1f6b377b7cd101f162addc990382e720bd99f8539
         | 
| 7 | 
            +
              data.tar.gz: 61fabf37f9ebd55b403f023e545c94e8a56bfea52058006f9f7c8a34c07a9f8d12580ca704dab629c99390d741c27d65dfd6e0ca53ecce597c282b846f9d77c1
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            // For format details, see https://aka.ms/devcontainer.json. For config options, see the
         | 
| 2 | 
            +
            // README at: https://github.com/devcontainers/templates/tree/main/src/ruby
         | 
| 3 | 
            +
            {
         | 
| 4 | 
            +
            	"name": "autotuner",
         | 
| 5 | 
            +
            	// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
         | 
| 6 | 
            +
            	"image": "ghcr.io/rails/devcontainer/images/ruby:3.4.7",
         | 
| 7 | 
            +
            	"features": {
         | 
| 8 | 
            +
            		"ghcr.io/devcontainers/features/github-cli:1": {}
         | 
| 9 | 
            +
            	}
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            	// Features to add to the dev container. More info: https://containers.dev/features.
         | 
| 12 | 
            +
            	// "features": {},
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            	// Use 'forwardPorts' to make a list of ports inside the container available locally.
         | 
| 15 | 
            +
            	// "forwardPorts": [],
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            	// Use 'postCreateCommand' to run commands after the container is created.
         | 
| 18 | 
            +
            	// "postCreateCommand": "ruby --version",
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            	// Configure tool-specific properties.
         | 
| 21 | 
            +
            	// "customizations": {},
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            	// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
         | 
| 24 | 
            +
            	// "remoteUser": "root"
         | 
| 25 | 
            +
            }
         | 
    
        data/.ruby-version
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            3. | 
| 1 | 
            +
            3.4.7
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -5,8 +5,8 @@ source "https://rubygems.org" | |
| 5 5 | 
             
            # Specify your gem's dependencies in autotuner.gemspec
         | 
| 6 6 | 
             
            gemspec
         | 
| 7 7 |  | 
| 8 | 
            -
            gem "rake", "~> 13. | 
| 8 | 
            +
            gem "rake", "~> 13.2"
         | 
| 9 9 |  | 
| 10 | 
            -
            gem "minitest", "~> 5. | 
| 10 | 
            +
            gem "minitest", "~> 5.26"
         | 
| 11 11 |  | 
| 12 | 
            -
            gem "rubocop", "~> 1. | 
| 12 | 
            +
            gem "rubocop", "~> 1.81"
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,57 +1,62 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                autotuner (1. | 
| 4 | 
            +
                autotuner (1.1.0)
         | 
| 5 5 |  | 
| 6 6 | 
             
            GEM
         | 
| 7 7 | 
             
              remote: https://rubygems.org/
         | 
| 8 8 | 
             
              specs:
         | 
| 9 | 
            -
                ast (2.4. | 
| 10 | 
            -
                json (2. | 
| 11 | 
            -
                language_server-protocol (3.17.0. | 
| 12 | 
            -
                 | 
| 13 | 
            -
                 | 
| 9 | 
            +
                ast (2.4.3)
         | 
| 10 | 
            +
                json (2.15.2)
         | 
| 11 | 
            +
                language_server-protocol (3.17.0.5)
         | 
| 12 | 
            +
                lint_roller (1.1.0)
         | 
| 13 | 
            +
                minitest (5.26.0)
         | 
| 14 | 
            +
                mocha (2.7.1)
         | 
| 14 15 | 
             
                  ruby2_keywords (>= 0.0.5)
         | 
| 15 | 
            -
                parallel (1. | 
| 16 | 
            -
                parser (3.3.0 | 
| 16 | 
            +
                parallel (1.27.0)
         | 
| 17 | 
            +
                parser (3.3.10.0)
         | 
| 17 18 | 
             
                  ast (~> 2.4.1)
         | 
| 18 19 | 
             
                  racc
         | 
| 19 | 
            -
                 | 
| 20 | 
            +
                prism (1.6.0)
         | 
| 21 | 
            +
                racc (1.8.1)
         | 
| 20 22 | 
             
                rainbow (3.1.1)
         | 
| 21 | 
            -
                rake (13.1 | 
| 22 | 
            -
                regexp_parser (2. | 
| 23 | 
            -
                 | 
| 24 | 
            -
                rubocop (1.62.1)
         | 
| 23 | 
            +
                rake (13.2.1)
         | 
| 24 | 
            +
                regexp_parser (2.11.3)
         | 
| 25 | 
            +
                rubocop (1.81.6)
         | 
| 25 26 | 
             
                  json (~> 2.3)
         | 
| 26 | 
            -
                  language_server-protocol ( | 
| 27 | 
            +
                  language_server-protocol (~> 3.17.0.2)
         | 
| 28 | 
            +
                  lint_roller (~> 1.1.0)
         | 
| 27 29 | 
             
                  parallel (~> 1.10)
         | 
| 28 30 | 
             
                  parser (>= 3.3.0.2)
         | 
| 29 31 | 
             
                  rainbow (>= 2.2.2, < 4.0)
         | 
| 30 | 
            -
                  regexp_parser (>=  | 
| 31 | 
            -
                   | 
| 32 | 
            -
                  rubocop-ast (>= 1.31.1, < 2.0)
         | 
| 32 | 
            +
                  regexp_parser (>= 2.9.3, < 3.0)
         | 
| 33 | 
            +
                  rubocop-ast (>= 1.47.1, < 2.0)
         | 
| 33 34 | 
             
                  ruby-progressbar (~> 1.7)
         | 
| 34 | 
            -
                  unicode-display_width (>= 2.4.0, <  | 
| 35 | 
            -
                rubocop-ast (1. | 
| 36 | 
            -
                  parser (>= 3.3. | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
                   | 
| 40 | 
            -
             | 
| 41 | 
            -
                  rubocop ( | 
| 35 | 
            +
                  unicode-display_width (>= 2.4.0, < 4.0)
         | 
| 36 | 
            +
                rubocop-ast (1.47.1)
         | 
| 37 | 
            +
                  parser (>= 3.3.7.2)
         | 
| 38 | 
            +
                  prism (~> 1.4)
         | 
| 39 | 
            +
                rubocop-minitest (0.38.2)
         | 
| 40 | 
            +
                  lint_roller (~> 1.1)
         | 
| 41 | 
            +
                  rubocop (>= 1.75.0, < 2.0)
         | 
| 42 | 
            +
                  rubocop-ast (>= 1.38.0, < 2.0)
         | 
| 43 | 
            +
                rubocop-shopify (2.17.1)
         | 
| 44 | 
            +
                  rubocop (~> 1.62)
         | 
| 42 45 | 
             
                ruby-progressbar (1.13.0)
         | 
| 43 46 | 
             
                ruby2_keywords (0.0.5)
         | 
| 44 | 
            -
                unicode-display_width (2. | 
| 47 | 
            +
                unicode-display_width (3.2.0)
         | 
| 48 | 
            +
                  unicode-emoji (~> 4.1)
         | 
| 49 | 
            +
                unicode-emoji (4.1.0)
         | 
| 45 50 |  | 
| 46 51 | 
             
            PLATFORMS
         | 
| 47 52 | 
             
              ruby
         | 
| 48 53 |  | 
| 49 54 | 
             
            DEPENDENCIES
         | 
| 50 55 | 
             
              autotuner!
         | 
| 51 | 
            -
              minitest (~> 5. | 
| 56 | 
            +
              minitest (~> 5.26)
         | 
| 52 57 | 
             
              mocha
         | 
| 53 | 
            -
              rake (~> 13. | 
| 54 | 
            -
              rubocop (~> 1. | 
| 58 | 
            +
              rake (~> 13.2)
         | 
| 59 | 
            +
              rubocop (~> 1.81)
         | 
| 55 60 | 
             
              rubocop-minitest
         | 
| 56 61 | 
             
              rubocop-shopify
         | 
| 57 62 |  | 
    
        data/README.md
    CHANGED
    
    | @@ -64,11 +64,23 @@ While autotuner aims to comprehensively analyze your traffic to give the suggest | |
| 64 64 | 
             
            ## Configuration
         | 
| 65 65 |  | 
| 66 66 | 
             
            - `Autotuner.enabled=`: (required, unless `Autotuner.sample_ratio` is set) Sets whether autotuner is enabled or not. When autotuner is disabled, data is not collected and suggestions are not given. Defaults to `false`.
         | 
| 67 | 
            -
            - `Autotuner.sample_ratio=`: (optional) Sets the portion of instances where autotuner is enabled. Pass a value between 0 (enabled on no  | 
| 67 | 
            +
            - `Autotuner.sample_ratio=`: (optional) Sets the portion of instances where autotuner is enabled. Pass a value between 0 (enabled on no instances) and 1.0 (enabled on all instances). Note that this does not sample requests, but rather samples the portion of instances that have autotuner enabled (it will be enabled for all requests on those instances). Do not configure `Autotuner.enabled=` when you use this option.
         | 
| 68 68 | 
             
            - `Autotuner.reporter=`: (required) Callback called when a heuristic is ready to give a suggestion. The callback will be called with one argument which will be an instance of `Autotuner::Report::Base`. Call `#to_s` on this object to get a string containing instructions and recommendations. You must set this when autotuner is enabled.
         | 
| 69 69 | 
             
            - `Autotuner.debug_reporter=`: (optional) Callback to periodically emit debug messages of internal state of heuristics. The callback will be called with one argument which will be a hash with the heuristic name as the key and the debug message as the value. Regular users do not need to configure this as this is only useful for debugging purposes.
         | 
| 70 70 | 
             
            - `Autotuner.metrics_reporter=`: (optional) Callback to emit useful metrics about your service. The callback will be called with a hash containing the metric names (string) as the key and integer values.
         | 
| 71 71 |  | 
| 72 | 
            +
            ## Emitted Metrics
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            The following metrics are passed to the `metrics_reporter` callback after each request.
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            | Name                  | Description |
         | 
| 77 | 
            +
            | --------------------- | ----------- |
         | 
| 78 | 
            +
            | `diff.time`           | Time spent doing garbage collection during the request. Produced by [GC::stat](https://docs.ruby-lang.org/en/master/GC.html#method-c-stat) |
         | 
| 79 | 
            +
            | `diff.minor_gc_count` | Number of minor garbage collections that occurred during the request. Produced by [GC::stat](https://docs.ruby-lang.org/en/master/GC.html#method-c-stat) |
         | 
| 80 | 
            +
            | `diff.major_gc_count` | Number of major garbage collections that occurred during the request. Produced by [GC::stat](https://docs.ruby-lang.org/en/master/GC.html#method-c-stat) |
         | 
| 81 | 
            +
            | `heap_pages`          | Number of heap pages in use after the request. Produced by [GC::stat](https://docs.ruby-lang.org/en/master/GC.html#method-c-stat) |
         | 
| 82 | 
            +
            | `request_time`        | Total duration of the request. |
         | 
| 83 | 
            +
             | 
| 72 84 | 
             
            ## Contributing
         | 
| 73 85 |  | 
| 74 86 | 
             
            Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/autotuner.
         | 
    
        data/autotuner.gemspec
    ADDED
    
    | @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "lib/autotuner/version"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |spec|
         | 
| 6 | 
            +
              spec.name = "autotuner"
         | 
| 7 | 
            +
              spec.version = Autotuner::VERSION
         | 
| 8 | 
            +
              spec.authors = ["Peter Zhu"]
         | 
| 9 | 
            +
              spec.email = ["peter@peterzhu.ca"]
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              spec.summary = "Get suggestions to tune Ruby's garbage collector"
         | 
| 12 | 
            +
              spec.homepage = "https://github.com/Shopify/autotuner"
         | 
| 13 | 
            +
              spec.license = "MIT"
         | 
| 14 | 
            +
              spec.required_ruby_version = ">= 3.1.0"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              spec.metadata["homepage_uri"] = spec.homepage
         | 
| 17 | 
            +
              spec.metadata["source_code_uri"] = "https://github.com/Shopify/autotuner"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              # Specify which files should be added to the gem when it is released.
         | 
| 20 | 
            +
              # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
         | 
| 21 | 
            +
              spec.files = Dir.chdir(__dir__) do
         | 
| 22 | 
            +
                %x(git ls-files -z).split("\x0").reject do |f|
         | 
| 23 | 
            +
                  (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              spec.bindir = "exe"
         | 
| 27 | 
            +
              spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
         | 
| 28 | 
            +
              spec.require_paths = ["lib"]
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              spec.add_development_dependency("mocha")
         | 
| 31 | 
            +
              spec.add_development_dependency("rubocop-minitest")
         | 
| 32 | 
            +
              spec.add_development_dependency("rubocop-shopify")
         | 
| 33 | 
            +
            end
         | 
| @@ -4,8 +4,6 @@ module Autotuner | |
| 4 4 | 
             
              module Heuristic
         | 
| 5 5 | 
             
                class GCCompact < Base
         | 
| 6 6 | 
             
                  class << self
         | 
| 7 | 
            -
                    private
         | 
| 8 | 
            -
             | 
| 9 7 | 
             
                    def supported?
         | 
| 10 8 | 
             
                      true
         | 
| 11 9 | 
             
                    end
         | 
| @@ -33,7 +31,7 @@ module Autotuner | |
| 33 31 | 
             
                    # Don't give suggestion twice
         | 
| 34 32 | 
             
                    @called_gc_compact = true
         | 
| 35 33 |  | 
| 36 | 
            -
                    Report::String.new(<<~MSG)
         | 
| 34 | 
            +
                    Report::String.new(name, <<~MSG)
         | 
| 37 35 | 
             
                      The following suggestion runs compaction at boot time, which reduces fragmentation inside of the Ruby heap. This can improve performance and reduce memory usage in forking web servers.
         | 
| 38 36 |  | 
| 39 37 | 
             
                      Before forking your web server, run the following Ruby code:
         | 
| @@ -41,10 +39,18 @@ module Autotuner | |
| 41 39 | 
             
                        3.times { GC.start }
         | 
| 42 40 | 
             
                        GC.compact
         | 
| 43 41 |  | 
| 44 | 
            -
                      For example,  | 
| 42 | 
            +
                      For example, with Puma, which runs its before fork hook once on boot (before the initial fork), add the following code into config/puma.rb:
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                        before_fork do
         | 
| 45 | 
            +
                          3.times { GC.start }
         | 
| 46 | 
            +
                          GC.compact
         | 
| 47 | 
            +
                        end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                      With Unicorn, which runs its before fork hook before each fork, add the following code into config/unicorn.rb:
         | 
| 45 50 |  | 
| 46 51 | 
             
                        compacted = false
         | 
| 47 52 | 
             
                        before_fork do
         | 
| 53 | 
            +
                          # avoid invalidating heap pages shared with previously forked children
         | 
| 48 54 | 
             
                          unless compacted
         | 
| 49 55 | 
             
                            3.times { GC.start }
         | 
| 50 56 | 
             
                            GC.compact
         | 
| @@ -4,8 +4,6 @@ module Autotuner | |
| 4 4 | 
             
              module Heuristic
         | 
| 5 5 | 
             
                class HeapSizeWarmup < Base
         | 
| 6 6 | 
             
                  class << self
         | 
| 7 | 
            -
                    private
         | 
| 8 | 
            -
             | 
| 9 7 | 
             
                    def supported?
         | 
| 10 8 | 
             
                      # Ruby 3.2 uses multiple heaps but does not support the
         | 
| 11 9 | 
             
                      # RUBY_GC_HEAP_%d_INIT_SLOTS environment variables, so we cannot
         | 
| @@ -99,7 +97,13 @@ module Autotuner | |
| 99 97 | 
             
                    # Don't generate report if there is nothing to report
         | 
| 100 98 | 
             
                    return if suggested_values.empty?
         | 
| 101 99 |  | 
| 102 | 
            -
                    Report::MultipleEnvironmentVariables.new( | 
| 100 | 
            +
                    Report::MultipleEnvironmentVariables.new(
         | 
| 101 | 
            +
                      name,
         | 
| 102 | 
            +
                      REPORT_ASSIST_MESSAGE,
         | 
| 103 | 
            +
                      env_names,
         | 
| 104 | 
            +
                      suggested_values,
         | 
| 105 | 
            +
                      configured_values,
         | 
| 106 | 
            +
                    )
         | 
| 103 107 | 
             
                  end
         | 
| 104 108 |  | 
| 105 109 | 
             
                  def debug_state
         | 
| @@ -4,8 +4,6 @@ module Autotuner | |
| 4 4 | 
             
              module Heuristic
         | 
| 5 5 | 
             
                class Malloc < Base
         | 
| 6 6 | 
             
                  class << self
         | 
| 7 | 
            -
                    private
         | 
| 8 | 
            -
             | 
| 9 7 | 
             
                    def supported?
         | 
| 10 8 | 
             
                      true
         | 
| 11 9 | 
             
                    end
         | 
| @@ -67,6 +65,7 @@ module Autotuner | |
| 67 65 | 
             
                    @given_suggestion = true
         | 
| 68 66 |  | 
| 69 67 | 
             
                    Report::MultipleEnvironmentVariables.new(
         | 
| 68 | 
            +
                      name,
         | 
| 70 69 | 
             
                      <<~MSG,
         | 
| 71 70 | 
             
                        The following suggestions reduce the number of minor garbage collection cycles, specifically a cycle called "malloc". Your app runs malloc cycles in approximately #{format("%.2f", malloc_gc_ratio * 100)}% of all minor garbage collection cycles.
         | 
| 72 71 |  | 
| @@ -4,8 +4,6 @@ module Autotuner | |
| 4 4 | 
             
              module Heuristic
         | 
| 5 5 | 
             
                class Oldmalloc < Base
         | 
| 6 6 | 
             
                  class << self
         | 
| 7 | 
            -
                    private
         | 
| 8 | 
            -
             | 
| 9 7 | 
             
                    def supported?
         | 
| 10 8 | 
             
                      true
         | 
| 11 9 | 
             
                    end
         | 
| @@ -66,6 +64,7 @@ module Autotuner | |
| 66 64 | 
             
                    @given_suggestion = true
         | 
| 67 65 |  | 
| 68 66 | 
             
                    Report::MultipleEnvironmentVariables.new(
         | 
| 67 | 
            +
                      name,
         | 
| 69 68 | 
             
                      <<~MSG,
         | 
| 70 69 | 
             
                        The following suggestions reduce the number of major garbage collection cycles, specifically a cycle called "oldmalloc". Your app runs oldmalloc cycles in approximately #{format("%.2f", oldmalloc_gc_ratio * 100)}% of all major garbage collection cycles.
         | 
| 71 70 |  | 
| @@ -4,8 +4,6 @@ module Autotuner | |
| 4 4 | 
             
              module Heuristic
         | 
| 5 5 | 
             
                class RememberedWBUnprotectedObjects < Base
         | 
| 6 6 | 
             
                  class << self
         | 
| 7 | 
            -
                    private
         | 
| 8 | 
            -
             | 
| 9 7 | 
             
                    def supported?
         | 
| 10 8 | 
             
                      # Ruby 3.3.0 and later have support RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO
         | 
| 11 9 | 
             
                      RUBY_VERSION >= "3.3.0"
         | 
| @@ -64,6 +62,7 @@ module Autotuner | |
| 64 62 | 
             
                    @given_suggestion = true
         | 
| 65 63 |  | 
| 66 64 | 
             
                    Report::SingleEnvironmentVariable.new(
         | 
| 65 | 
            +
                      name,
         | 
| 67 66 | 
             
                      <<~MSG,
         | 
| 68 67 | 
             
                        The following suggestions reduce the number of major garbage collection cycles, specifically a cycle called "remembered write barrier unprotected" (also know as "shady" due to historical reasons). Your app runs remembered write barrier unprotected cycles in approximately #{format("%.2f", wb_unprotected_gc_ratio * 100)}% of all major garbage collection cycles.
         | 
| 69 68 |  | 
    
        data/lib/autotuner/heuristics.rb
    CHANGED
    
    | @@ -3,10 +3,10 @@ | |
| 3 3 | 
             
            module Autotuner
         | 
| 4 4 | 
             
              module Heuristics
         | 
| 5 5 | 
             
                HEURISTICS = Heuristic::Base.subclasses.freeze
         | 
| 6 | 
            -
                 | 
| 6 | 
            +
                SUPPORTED_HEURISTICS = HEURISTICS.dup.keep_if(&:supported?).freeze
         | 
| 7 7 |  | 
| 8 | 
            -
                def  | 
| 9 | 
            -
                   | 
| 8 | 
            +
                def supported_heuristics
         | 
| 9 | 
            +
                  SUPPORTED_HEURISTICS
         | 
| 10 10 | 
             
                end
         | 
| 11 11 | 
             
              end
         | 
| 12 12 | 
             
            end
         | 
| @@ -7,9 +7,10 @@ module Autotuner | |
| 7 7 | 
             
                    It is always recommended to experiment with these suggestions as some suggestions may not always yield positive performance improvements. The recommended method is to perform A/B testing where a portion of traffic does not have the these suggested values and a portion of traffic with these suggested values.
         | 
| 8 8 | 
             
                  MSG
         | 
| 9 9 |  | 
| 10 | 
            -
                  attr_reader :assist_message
         | 
| 10 | 
            +
                  attr_reader :heuristic_name, :assist_message
         | 
| 11 11 |  | 
| 12 | 
            -
                  def initialize(assist_message)
         | 
| 12 | 
            +
                  def initialize(heuristic_name, assist_message)
         | 
| 13 | 
            +
                    @heuristic_name = heuristic_name
         | 
| 13 14 | 
             
                    @assist_message = assist_message
         | 
| 14 15 | 
             
                  end
         | 
| 15 16 |  | 
| @@ -7,8 +7,8 @@ module Autotuner | |
| 7 7 | 
             
                  attr_reader :suggested_value
         | 
| 8 8 | 
             
                  attr_reader :configured_value
         | 
| 9 9 |  | 
| 10 | 
            -
                  def initialize(assist_message, env_name, suggested_value, configured_value)
         | 
| 11 | 
            -
                    super(assist_message)
         | 
| 10 | 
            +
                  def initialize(heuristic_name, assist_message, env_name, suggested_value, configured_value)
         | 
| 11 | 
            +
                    super(heuristic_name, assist_message)
         | 
| 12 12 | 
             
                    @env_name = env_name
         | 
| 13 13 | 
             
                    @suggested_value = suggested_value
         | 
| 14 14 | 
             
                    @configured_value = configured_value
         | 
| @@ -25,7 +25,7 @@ module Autotuner | |
| 25 25 | 
             
                  end
         | 
| 26 26 |  | 
| 27 27 | 
             
                  def suggested_tuning_str(env, suggested, configured)
         | 
| 28 | 
            -
                    str =  | 
| 28 | 
            +
                    str = "  #{env}=#{suggested}"
         | 
| 29 29 | 
             
                    str << " (configured value: #{configured})" if configured
         | 
| 30 30 | 
             
                    str << "\n"
         | 
| 31 31 | 
             
                    str
         | 
| @@ -7,8 +7,8 @@ module Autotuner | |
| 7 7 | 
             
                  attr_reader :suggested_value
         | 
| 8 8 | 
             
                  attr_reader :configured_value
         | 
| 9 9 |  | 
| 10 | 
            -
                  def initialize(assist_message, env_name, suggested_value, configured_value)
         | 
| 11 | 
            -
                    super(assist_message)
         | 
| 10 | 
            +
                  def initialize(heuristic_name, assist_message, env_name, suggested_value, configured_value)
         | 
| 11 | 
            +
                    super(heuristic_name, assist_message)
         | 
| 12 12 |  | 
| 13 13 | 
             
                    @env_name = env_name
         | 
| 14 14 | 
             
                    @suggested_value = suggested_value
         | 
| @@ -5,8 +5,6 @@ module Autotuner | |
| 5 5 | 
             
                HEURISTICS_POLLING_FREQUENCY = 100
         | 
| 6 6 | 
             
                DEBUG_EMIT_FREQUENCY = 1000
         | 
| 7 7 |  | 
| 8 | 
            -
                attr_reader :heuristics
         | 
| 9 | 
            -
             | 
| 10 8 | 
             
                def initialize
         | 
| 11 9 | 
             
                  @request_count = 0
         | 
| 12 10 |  | 
| @@ -14,7 +12,7 @@ module Autotuner | |
| 14 12 |  | 
| 15 13 | 
             
                  @system_context = SystemContext.new
         | 
| 16 14 |  | 
| 17 | 
            -
                  @heuristics = Autotuner. | 
| 15 | 
            +
                  @heuristics = Autotuner.supported_heuristics.map { |h| h.new(@system_context) }
         | 
| 18 16 | 
             
                end
         | 
| 19 17 |  | 
| 20 18 | 
             
                def request
         | 
| @@ -27,6 +25,16 @@ module Autotuner | |
| 27 25 |  | 
| 28 26 | 
             
                private
         | 
| 29 27 |  | 
| 28 | 
            +
                def enabled_heuristics
         | 
| 29 | 
            +
                  Enumerator.new do |y|
         | 
| 30 | 
            +
                    @heuristics.each do |heuristic|
         | 
| 31 | 
            +
                      next unless heuristic.class.enabled?
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                      y << heuristic
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 30 38 | 
             
                def before_request
         | 
| 31 39 | 
             
                  @request_context.before_request
         | 
| 32 40 |  | 
| @@ -38,7 +46,7 @@ module Autotuner | |
| 38 46 |  | 
| 39 47 | 
             
                  @system_context.update(@request_context)
         | 
| 40 48 |  | 
| 41 | 
            -
                   | 
| 49 | 
            +
                  enabled_heuristics.each do |heuristic|
         | 
| 42 50 | 
             
                    heuristic.call(@request_context)
         | 
| 43 51 | 
             
                  end
         | 
| 44 52 |  | 
| @@ -48,7 +56,7 @@ module Autotuner | |
| 48 56 | 
             
                end
         | 
| 49 57 |  | 
| 50 58 | 
             
                def emit_heuristic_reports
         | 
| 51 | 
            -
                   | 
| 59 | 
            +
                  enabled_heuristics.each do |heuristic|
         | 
| 52 60 | 
             
                    report = heuristic.tuning_report
         | 
| 53 61 |  | 
| 54 62 | 
             
                    next unless report
         | 
| @@ -68,7 +76,7 @@ module Autotuner | |
| 68 76 | 
             
                    system_context: @system_context.debug_state,
         | 
| 69 77 | 
             
                  }
         | 
| 70 78 |  | 
| 71 | 
            -
                   | 
| 79 | 
            +
                  enabled_heuristics.each do |h|
         | 
| 72 80 | 
             
                    debug_states[h.name] = h.debug_state
         | 
| 73 81 | 
             
                  end
         | 
| 74 82 |  | 
    
        data/lib/autotuner/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: autotuner
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0 | 
| 4 | 
            +
              version: 1.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Peter Zhu
         | 
| 8 | 
            -
            autorequire:
         | 
| 9 8 | 
             
            bindir: exe
         | 
| 10 9 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 10 | 
            +
            date: 1980-01-02 00:00:00.000000000 Z
         | 
| 12 11 | 
             
            dependencies:
         | 
| 13 12 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 13 | 
             
              name: mocha
         | 
| @@ -52,13 +51,13 @@ dependencies: | |
| 52 51 | 
             
                - - ">="
         | 
| 53 52 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 53 | 
             
                    version: '0'
         | 
| 55 | 
            -
            description:
         | 
| 56 54 | 
             
            email:
         | 
| 57 55 | 
             
            - peter@peterzhu.ca
         | 
| 58 56 | 
             
            executables: []
         | 
| 59 57 | 
             
            extensions: []
         | 
| 60 58 | 
             
            extra_rdoc_files: []
         | 
| 61 59 | 
             
            files:
         | 
| 60 | 
            +
            - ".devcontainer/devcontainer.json"
         | 
| 62 61 | 
             
            - ".rubocop.yml"
         | 
| 63 62 | 
             
            - ".ruby-version"
         | 
| 64 63 | 
             
            - Gemfile
         | 
| @@ -66,6 +65,7 @@ files: | |
| 66 65 | 
             
            - LICENSE.txt
         | 
| 67 66 | 
             
            - README.md
         | 
| 68 67 | 
             
            - Rakefile
         | 
| 68 | 
            +
            - autotuner.gemspec
         | 
| 69 69 | 
             
            - lib/autotuner.rb
         | 
| 70 70 | 
             
            - lib/autotuner/configuration.rb
         | 
| 71 71 | 
             
            - lib/autotuner/data_structure/data_points.rb
         | 
| @@ -92,7 +92,6 @@ licenses: | |
| 92 92 | 
             
            metadata:
         | 
| 93 93 | 
             
              homepage_uri: https://github.com/Shopify/autotuner
         | 
| 94 94 | 
             
              source_code_uri: https://github.com/Shopify/autotuner
         | 
| 95 | 
            -
            post_install_message:
         | 
| 96 95 | 
             
            rdoc_options: []
         | 
| 97 96 | 
             
            require_paths:
         | 
| 98 97 | 
             
            - lib
         | 
| @@ -107,8 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 107 106 | 
             
                - !ruby/object:Gem::Version
         | 
| 108 107 | 
             
                  version: '0'
         | 
| 109 108 | 
             
            requirements: []
         | 
| 110 | 
            -
            rubygems_version: 3. | 
| 111 | 
            -
            signing_key:
         | 
| 109 | 
            +
            rubygems_version: 3.6.9
         | 
| 112 110 | 
             
            specification_version: 4
         | 
| 113 111 | 
             
            summary: Get suggestions to tune Ruby's garbage collector
         | 
| 114 112 | 
             
            test_files: []
         |