puma_auto_tune 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ae138aad2de4355bff1e6ca326819e19e314833f
4
+ data.tar.gz: c4a2411f07991c426e532929e6822167bb18c671
5
+ SHA512:
6
+ metadata.gz: 0232c6f1ed6ba0ce7c4070758c2a4d5fbc4bef59224183afe867c7659a1a74ab9c5f56bb0d78ac1279793fde4681b2048e516444e893d8e3d83c7a8e7b9b4471
7
+ data.tar.gz: 9f8812bb72f44646c69ef51ba7cec68c49bc37cdc95aa9a3cd9e51f8802916872f275279c6defa04c036598caa4201908126263410125e717a37a8f3b3940455
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ test/logs/
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - ruby-head
7
+ - jruby-19mode
8
+ - rbx-19mode
9
+
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ - rvm: rbx-19mode
14
+ - rvm: jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
@@ -0,0 +1,200 @@
1
+ # Puma Auto Tune
2
+
3
+ [![Build Status](https://travis-ci.org/schneems/puma_auto_tune.png?branch=master)](https://travis-ci.org/schneems/puma_auto_tune)
4
+
5
+ ## What
6
+
7
+ Performance without the (T)pain: `puma_auto_tune` will automatically adjust the number of [puma](https://github.com/puma/puma) workers to optimize the performance of your Ruby web application.
8
+
9
+ ## How
10
+
11
+ Puma is a web server that allows you to adjust the amount of processes and threads it uses to process requests. At a very simple level the more processes and threads you have the more requests you can process concurrently. However this comes at a cost, more processes means more RAM and more threads means more CPU usage. You want to get as close to maxing out your resources without going over.
12
+
13
+ The amount of memory and CPU your program consumes is also a factor of your code, as well as the amount of load it is under. Larger applications require more RAM. More requests mean more Ruby objects are created and garbage collected as your application generates web pages. Because of these factors, there is no one size fits all number for workers and threads, that's where Puma Auto Tune comes in.
14
+
15
+ Run Puma Auto Tune in production under load, or in staging while simulating load with tools like [siege](http://www.joedog.org/siege-home/), [blitz.io](https://www.blitz.io/), or [flood.io](https://flood.io/) for a long enough time and we will compute and set your application numbers to maximize concurrent requests without going over your system limits.
16
+
17
+ Currently Puma Auto Tune will optimize the number of workers (processes) based on RAM.
18
+
19
+ ## Install
20
+
21
+ In your `Gemfile` add:
22
+
23
+ ```ruby
24
+ gem 'puma_auto_tune'
25
+ ```
26
+
27
+ Then run `$ bundle install`.
28
+
29
+ ## Use
30
+
31
+ In your application call:
32
+
33
+ ```ruby
34
+ PumaAutoTune.start
35
+ ```
36
+
37
+ In Rails you could place this in an initializer such as `config/initializers/puma_auto_tune.rb`.
38
+
39
+ Puma Auto Tune will attempt to find an ideal number of workers for your application.
40
+
41
+
42
+ ## Config
43
+
44
+ You will need to configure your Puma Auto Tune to be aware of the maximum amount of RAM it can use.
45
+
46
+ ```ruby
47
+ PumaAutoTune.config do |config|
48
+ config.ram = 512 # mb: available on system
49
+ end
50
+ ```
51
+
52
+ The default is `512` which matches the amount of ram available on a Heroku dyno. There are a few other advanced config options:
53
+
54
+ ```ruby
55
+ PumaAutoTune.config do |config|
56
+ config.ram = 1024 # mb: available on system
57
+ config.frequency = 20 # seconds: the duration to check memory usage
58
+ config.reap_duration = 30 # seconds: how long `reap_cycle` will be run for
59
+ end
60
+ ```
61
+
62
+ To see defaults check out [puma_auto_tune.rb](lib/puma_auto_tune/puma_auto_tune.rb)
63
+
64
+
65
+ ## Hitting the Sweet Spot
66
+
67
+ Puma Auto Tune is designed to tune the number of workers for a given application while it is running. Once you restart the program the tuning must start over. Once the algorithm has found the "sweet spot" you can maximize your application throughput by manually setting the number of `workers` that puma starts with. To help you do this Puma Auto Tune outputs semi-regular logs with formatted values.
68
+
69
+ ```
70
+ puma.resource_ram_mb=476.6328125 puma.current_cluster_size=5
71
+ ```
72
+
73
+ You can use a service such as [librato](https://metrics.librato.com/) to pull values out of your logs and graph them. When you see over time that your server settles on a given `cluster_size` you should set this as your default `puma -w $PUMA_WORKERS` if you're using the CLI to start your app or if you're using a `config/puma.rb` file:
74
+
75
+ ```ruby
76
+ workers Integer(ENV['PUMA_WORKERS'] || 3)
77
+ ```
78
+
79
+ ## Puma Worker Killer
80
+
81
+ Do not use with `puma_worker_killer` gem. Puma Auto Tune takes care of memory leaks in addition to tuning your puma workers.
82
+
83
+
84
+ ## How it Works: Tuning Algorithm (RAM)
85
+
86
+ Simple by default, custom for true Puma hackers. The best way to think of the tuner is to start with the different states of memory consumption Puma can be under:
87
+
88
+ - Unused RAM: we can add a worker
89
+ - Memory leak (too much RAM usage): we should restart a worker
90
+ - Too much RAM usage: we can remove a worker
91
+ - Just right: No need to scale up or down.
92
+
93
+ The algorithm will periodically get the total memory used by Puma and take action appropriately.
94
+
95
+ #### Memory States: Unused RAM
96
+
97
+ The memory of the smallest worker is recorded. If adding another worker does not put the total memory over the threshold then one will be added.
98
+
99
+ #### Memory States: Memory Leak (too much RAM usage)
100
+
101
+ When the amount of memory is more than that on the system, we assume a memory leak and restart the largest worker. This will trigger a check to determine if the result was due to a memory leak or because we have too many workers.
102
+
103
+ #### Memory States: Too much RAM Usage
104
+
105
+ After a worker has been restarted we will aggressively check for memory usage for a fixed period of time, default is 90 seconds(`PumaAutoTune.reap_reap_duration`). If memory goes over the limit, it is assumed that the cause is due to excess workers. The number of workers will be decreased by one. Puma Auto Tune will record the number of total workers that were present when we went over and set this as a new maximum worker number. After removing a process, Puma Auto Tune again checks for memory overages for the same duration and continues to decrement the number of workers until the total memory consumed is under the maximum.
106
+
107
+ #### Memory States: Just Right
108
+
109
+ Periodically the tuner will wake up and take note of memory usage. If it cannot scale up, and doesn't need to scale down it goes back to sleep.
110
+
111
+ ## Customizing the Algorithm
112
+
113
+ Here's the fun part. You can write your own algorithm using the included hook system. The default algorithm is implemented as a series of [pre-defined hooks](lib/puma_auto_tune/defaults/ram/hooks.rb).
114
+
115
+ You can over-write one or more of the hooks to add custom behavior. To define hooks call:
116
+
117
+ ```ruby
118
+ PumaAutoTune.hooks(:ram) do |auto|
119
+
120
+ end
121
+ ```
122
+
123
+ Each hook has a name and can be over-written by calling `set` and passing in the symbol of the hook you wish to over-write. These are the default RAM hooks:
124
+
125
+ - `:cycle`
126
+ - `:reap_cycle`
127
+ - `:out_of_memory`
128
+ - `:under_memory`
129
+ - `:add_worker`
130
+ - `:remove_worker`
131
+
132
+
133
+ Once you have the hook object you can use the `call` method to jump to other hooks.
134
+
135
+ ### Cycle
136
+
137
+ This is the main event loop of your program. This code will be called every `PumaAutoTune.frequency` seconds. To over-write you can do this:
138
+
139
+
140
+ ```ruby
141
+ PumaAutoTune.hooks(:ram) do |auto|
142
+ auto.set(:cycle) do |memory, master, workers|
143
+ if memory > PumaAutoTune.ram # mb
144
+ auto.call(:out_of_memory)
145
+ else
146
+ auto.call(:under_memory) if memory + workers.last.memory
147
+ end
148
+ end
149
+ end
150
+ ```
151
+
152
+ ### Reap Cycle
153
+
154
+ When you think you might run out of memory call the `reap_cycle`. The code in this hook will be called in a loop for `PumaAutoTune.reap_duration` seconds.
155
+
156
+ ```ruby
157
+ PumaAutoTune.hooks do |auto|
158
+ auto.set(:reap_cycle) do |memory, master, workers|
159
+ if memory > PumaAutoTune.ram
160
+ auto.call(:remove_worker)
161
+ end
162
+ end
163
+ end
164
+ ```
165
+
166
+ ## Add Worker
167
+
168
+ Bumps up the worker size by one.
169
+
170
+ ```ruby
171
+ PumaAutoTune.hooks do |auto|
172
+ auto.set(:add_worker) do |memory, master, workers|
173
+ auto.log "Cluster too small. Resizing to add one more worker"
174
+ master.add_worker
175
+ auto.call(:reap_cycle)
176
+ e
177
+ end
178
+ ```
179
+
180
+ Here we're calling `:reap_cycle` just in case we accidentally went over our memory limit after the increase.
181
+
182
+ ## Remove Worker
183
+
184
+ Removes a worker. When `remove_worker` is called it will automatically set `PumaAutoTune.max_workers` to be one less than the current number of workers.
185
+
186
+ ```ruby
187
+ PumaAutoTune.hooks do |hook|
188
+ auto.set(:remove_worker) do |memory, master, workers|
189
+ auto.log "Cluster too large. Resizing to remove one worker"
190
+ master.remove_worker
191
+ auto.call(:reap_cycle)
192
+ end
193
+ end
194
+ ```
195
+
196
+ In case removing one worker wasn't enough we call `reap_cycle` again. Once a worker has been flagged with `restart` it will report zero RAM usage even if it has not completely terminated.
197
+
198
+ ## License
199
+
200
+ MIT
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'bundler/gem_tasks'
4
+
5
+ require 'rake'
6
+ require 'rake/testtask'
7
+
8
+ task :default => [:test]
9
+
10
+ test_task = Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.libs << 'test'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = false
15
+ end
@@ -0,0 +1,44 @@
1
+ require 'get_process_mem'
2
+
3
+ module PumaAutoTune; end
4
+
5
+ require 'puma_auto_tune/version'
6
+ require 'puma_auto_tune/master'
7
+ require 'puma_auto_tune/worker'
8
+ require 'puma_auto_tune/memory'
9
+
10
+
11
+ module PumaAutoTune
12
+ INFINITY = 1/0.0
13
+ RESOURCES = { ram: PumaAutoTune::Memory.new }
14
+
15
+ extend self
16
+
17
+ attr_accessor :ram, :max_workers, :frequency, :reap_duration
18
+ self.ram = 512 # mb
19
+ self.max_workers = INFINITY
20
+ self.frequency = 10 # seconds
21
+ self.reap_duration = 90 # seconds
22
+
23
+
24
+ def self.config
25
+ yield self
26
+ self
27
+ end
28
+
29
+ def self.hooks(name = nil, resource = nil, &block)
30
+ @hooks ||= {}
31
+ return @hooks if name.nil?
32
+ resource ||= RESOURCES[name] || raise("no default resource specified for #{name.inspect}")
33
+ @hooks[name] ||= Hook.new(resource)
34
+ block.call(@hooks[name]) if block
35
+ @hooks[name]
36
+ end
37
+
38
+ def start
39
+ hooks.map {|name, hook| hook.auto_cycle}
40
+ end
41
+ end
42
+
43
+
44
+ require 'puma_auto_tune/hook'
@@ -0,0 +1,52 @@
1
+ ## This is the default algorithm
2
+ PumaAutoTune.hooks(:ram) do |auto|
3
+ # Runs in a continual loop controlled by PumaAutoTune.frequency
4
+ auto.set(:cycle) do |memory, master, workers|
5
+ if memory > PumaAutoTune.ram # mb
6
+ auto.call(:out_of_memory)
7
+ else
8
+ auto.call(:under_memory) if memory + workers.last.memory
9
+ end
10
+ end
11
+
12
+ # Called repeatedly for `PumaAutoTune.reap_duration`.
13
+ # call when you think you may have too many workers
14
+ auto.set(:reap_cycle) do |memory, master, workers|
15
+ if memory > PumaAutoTune.ram
16
+ auto.call(:remove_worker)
17
+ end
18
+ end
19
+
20
+ # Called when puma is using too much memory
21
+ auto.set(:out_of_memory) do |memory, master, workers|
22
+ largest_worker = workers.last # ascending worker size
23
+ auto.log "Potential memory leak. Reaping largest worker", largest_worker_memory_mb: largest_worker.memory
24
+ largest_worker.restart
25
+ auto.call(:reap_cycle)
26
+ end
27
+
28
+ # Called when puma is not using all available memory
29
+ # PumaAutoTune.max_workers is tracked automatically by `remove_worker`
30
+ auto.set(:under_memory) do |memory, master, workers|
31
+ theoretical_max_mb = memory + workers.first.memory # assending worker size
32
+ if theoretical_max_mb < PumaAutoTune.ram && workers.size + 1 < PumaAutoTune.max_workers
33
+ auto.call(:add_worker)
34
+ else
35
+ auto.log "All is well"
36
+ end
37
+ end
38
+
39
+ # Called to add an extra worker
40
+ auto.set(:add_worker) do |memory, master, workers|
41
+ auto.log "Cluster too small. Resizing to add one more worker"
42
+ master.add_worker
43
+ auto.call(:reap_cycle)
44
+ end
45
+
46
+ # Called to remove 1 worker from pool. Sets maximum size
47
+ auto.set(:remove_worker) do |memory, master, workers|
48
+ auto.log "Cluster too large. Resizing to remove one worker"
49
+ master.remove_worker
50
+ auto.call(:reap_cycle)
51
+ end
52
+ end
@@ -0,0 +1,19 @@
1
+ PumaAutoTune.hooks(:ram) do |auto|
2
+ auto.wrap(:reap_cycle) do |block|
3
+ Proc.new do |resource, master, workers|
4
+ ends_at = Time.now - PumaAutoTune.reap_duration
5
+ while Time.now < ends_at
6
+ sleep 1
7
+ block.call(*auto.args)
8
+ end
9
+ end
10
+ end
11
+
12
+ auto.wrap(:remove_worker) do |block|
13
+ Proc.new do |resource, master, workers|
14
+ resource.reset
15
+ PumaAutoTune.max_workers = workers.size - 1
16
+ block.call(*auto.args)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ module PumaAutoTune
2
+ class Hook
3
+
4
+ def initialize(resource)
5
+ @resource = resource
6
+ @started = Time.now
7
+ @hooks = {}
8
+ @wraps = {}
9
+ end
10
+
11
+ def define_hook(name, &block)
12
+ wrap_hook(name)
13
+ @hooks[name] = block
14
+ end
15
+ alias :set :define_hook
16
+
17
+ def call(name)
18
+ hook = @hooks[name] or raise "No such hook #{name.inspect}. Available: #{@hooks.keys.inspect}"
19
+ hook.call(self.args)
20
+ end
21
+
22
+ def wrap_hook(name, &block)
23
+ if block
24
+ @wraps[name] = block
25
+ else
26
+ if wrap = @wraps[name]
27
+ @hooks[name] = wrap.call(@hooks[name])
28
+ end
29
+ end
30
+ end
31
+ alias :wrap :wrap_hook
32
+
33
+ def auto_cycle
34
+ Thread.new do
35
+ loop do
36
+ sleep PumaAutoTune.frequency
37
+ call(:cycle) if @resource.master.running?
38
+ end
39
+ end
40
+ end
41
+
42
+ def log(msg, options = {})
43
+ elapsed = (Time.now - @started).ceil
44
+ msg = ["PumaAutoTune (#{elapsed}s): #{msg}"]
45
+
46
+ options[@resource.name] = @resource.amount
47
+ options["current_cluster_size"] = @resource.workers.size
48
+ options.each { |k, v| msg << "puma.#{k.to_s.downcase}=#{v}" }
49
+ puts msg.join(" ")
50
+ end
51
+
52
+ def args
53
+ @resource.reset
54
+ [@resource.amount, @resource.master, @resource.workers]
55
+ end
56
+ end
57
+ end
58
+
59
+ require 'puma_auto_tune/defaults/ram/wrappers'
60
+ require 'puma_auto_tune/defaults/ram/hooks'
@@ -0,0 +1,45 @@
1
+ module PumaAutoTune
2
+ class Master
3
+ def initialize(master = nil)
4
+ @master = master || get_master
5
+ end
6
+
7
+ def running?
8
+ @master && workers.any?
9
+ end
10
+
11
+ # https://github.com/puma/puma/blob/master/docs/signals.md#puma-signals
12
+ def remove_worker
13
+ send_signal("TTOU")
14
+ end
15
+
16
+ # https://github.com/puma/puma/blob/master/docs/signals.md#puma-signals
17
+ def add_worker
18
+ send_signal("TTIN")
19
+ end
20
+
21
+ # less cryptic interface
22
+ def send_signal(signal, pid = Process.pid)
23
+ Process.kill(signal, pid)
24
+ end
25
+
26
+ def memory
27
+ @memory
28
+ end
29
+ alias :mb :memory
30
+
31
+ def get_memory
32
+ @memory = ::GetProcessMem.new(Process.pid).mb
33
+ end
34
+
35
+ def workers
36
+ @master.instance_variable_get("@workers").map {|w| PumaAutoTune::Worker.new(w) }
37
+ end
38
+
39
+ private
40
+
41
+ def get_master
42
+ ObjectSpace.each_object(Puma::Cluster).map { |obj| obj }.first if defined?(Puma::Cluster)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,41 @@
1
+ require 'delegate'
2
+
3
+ module PumaAutoTune
4
+
5
+ class Memory
6
+ attr_accessor :master, :workers
7
+
8
+ def initialize(master = PumaAutoTune::Master.new)
9
+ @master = master
10
+ end
11
+
12
+ def name
13
+ "resource_ram_mb"
14
+ end
15
+
16
+ def amount
17
+ @mb ||= begin
18
+ worker_memory = workers.map {|w| w.memory }.inject(&:+) || 0
19
+ worker_memory + @master.get_memory
20
+ end
21
+ end
22
+
23
+ def largest_worker
24
+ workers.last
25
+ end
26
+
27
+ def smallest_worker
28
+ workers.first
29
+ end
30
+
31
+ def workers
32
+ workers ||= @master.workers.sort_by! {|w| w.get_memory }
33
+ end
34
+
35
+ def reset
36
+ raise "must set master" unless @master
37
+ @workers = nil
38
+ @mb = nil
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module PumaAutoTune
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,35 @@
1
+ module PumaAutoTune
2
+ class Worker
3
+
4
+ def initialize(worker)
5
+ @worker = worker
6
+ end
7
+
8
+ def memory
9
+ @memory || get_memory
10
+ end
11
+ alias :mb :memory
12
+
13
+ def get_memory
14
+ @memory = if restarting?
15
+ 0
16
+ else
17
+ ::GetProcessMem.new(self.pid).mb
18
+ end
19
+ end
20
+
21
+ def restarting?
22
+ @restarting
23
+ end
24
+
25
+
26
+ def restart
27
+ @restarting = true
28
+ @worker.term
29
+ end
30
+
31
+ def pid
32
+ @worker.pid
33
+ end
34
+ end
35
+ end
data/my.log ADDED
File without changes
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'puma_auto_tune/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "puma_auto_tune"
8
+ gem.version = PumaAutoTune::VERSION
9
+ gem.authors = ["Richard Schneeman"]
10
+ gem.email = ["richard.schneeman+rubygems@gmail.com"]
11
+ gem.description = %q{ Puma performance without all the (T)pain }
12
+ gem.summary = %q{ }
13
+ gem.homepage = "https://github.com/schneems/puma_auto_tune"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+
22
+ gem.add_dependency "puma", "~> 2.7"
23
+ gem.add_dependency "get_process_mem", "~> 0"
24
+ gem.add_development_dependency "rake", "~> 10.1"
25
+ end
@@ -0,0 +1,14 @@
1
+ require 'rack'
2
+ require 'rack/server'
3
+
4
+ run Proc.new {|env| [200, {}, ['Hello World']] }
5
+
6
+
7
+
8
+ require 'puma_auto_tune'
9
+
10
+ PumaAutoTune.config do |config|
11
+ config.ram = Integer(ENV['PUMA_RAM']) if ENV['PUMA_RAM']
12
+ config.frequency = Integer(ENV['PUMA_FREQUENCY']) if ENV['PUMA_FREQUENCY']
13
+ end
14
+ PumaAutoTune.start
@@ -0,0 +1,11 @@
1
+ threads Integer(ENV['MIN_THREADS'] || 1), Integer(ENV['MAX_THREADS'] || 16)
2
+ workers Integer(ENV['PUMA_WORKERS'] || 3)
3
+
4
+ port ENV['PORT'] || 0 # using 0 tells the OS to grab first open port
5
+ environment ENV['RACK_ENV'] || 'development'
6
+ preload_app!
7
+
8
+ Thread.abort_on_exception = true
9
+
10
+ on_worker_boot do
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class PumaAutoTuneTest < Test::Unit::TestCase
4
+
5
+ def teardown
6
+ @puma.shutdown if @puma
7
+ end
8
+
9
+ def test_starts
10
+ @puma = PumaRemote.new.spawn
11
+ @puma.wait
12
+ assert_match "PumaAutoTune", @puma.log.read
13
+ end
14
+
15
+ end
@@ -0,0 +1,50 @@
1
+ Bundler.require
2
+
3
+ require 'test/unit'
4
+
5
+ class PumaRemote
6
+
7
+ attr_accessor :path, :frequency, :config, :log, :ram, :pid
8
+
9
+ def initialize(options = {})
10
+ @path = options[:path] || fixture_path("app.ru")
11
+ @frequency = options[:frequency] || 1
12
+ @config = options[:config] || fixture_path("config.rb")
13
+ @log = options[:log] || new_log_file
14
+ @ram = options[:ram] || 512
15
+ end
16
+
17
+ def wait
18
+ until log.read.match %r{booted}
19
+ sleep 1
20
+ end
21
+ sleep 1
22
+ self
23
+ end
24
+
25
+ def shutdown
26
+ if pid
27
+ Process.kill('TERM', pid)
28
+ Process.wait(pid)
29
+ end
30
+
31
+ FileUtils.remove_entry_secure log
32
+ end
33
+
34
+ def spawn
35
+ FileUtils.mkdir_p(log.dirname)
36
+ FileUtils.touch(log)
37
+ @pid = Process.spawn("exec env PUMA_FREQUENCY=#{frequency} PUMA_RAM=#{ram} bundle exec puma #{path} -C #{config} > #{log}")
38
+ self
39
+ end
40
+
41
+ def new_log_file
42
+ Pathname.new("test/logs/puma_#{rand(1...2000)}_#{Time.now.to_f}.log")
43
+ end
44
+
45
+ def fixture_path(name = nil)
46
+ path = Pathname.new(File.expand_path("../fixtures", __FILE__))
47
+ return path.join(name) if name
48
+ path
49
+ end
50
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puma_auto_tune
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Richard Schneeman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: puma
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: get_process_mem
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.1'
55
+ description: " Puma performance without all the (T)pain "
56
+ email:
57
+ - richard.schneeman+rubygems@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - Gemfile
65
+ - README.md
66
+ - Rakefile
67
+ - lib/puma_auto_tune.rb
68
+ - lib/puma_auto_tune/defaults/ram/hooks.rb
69
+ - lib/puma_auto_tune/defaults/ram/wrappers.rb
70
+ - lib/puma_auto_tune/hook.rb
71
+ - lib/puma_auto_tune/master.rb
72
+ - lib/puma_auto_tune/memory.rb
73
+ - lib/puma_auto_tune/version.rb
74
+ - lib/puma_auto_tune/worker.rb
75
+ - my.log
76
+ - puma_auto_tune.gemspec
77
+ - test/fixtures/app.ru
78
+ - test/fixtures/config.rb
79
+ - test/puma_auto_tune_test.rb
80
+ - test/test_helper.rb
81
+ homepage: https://github.com/schneems/puma_auto_tune
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.2.2
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: ''
105
+ test_files:
106
+ - test/fixtures/app.ru
107
+ - test/fixtures/config.rb
108
+ - test/puma_auto_tune_test.rb
109
+ - test/test_helper.rb