Browse Source

[ruby/padrino] Use auto_tune.rb for Puma and Unicorn config (#8522)

Use the same script that is used by other Ruby frameworks.
Datamapper has a connection pool of 8, so that should be the max
concurrency.
Petrik de Heus 1 year ago
parent
commit
2d4ada54ae

+ 41 - 0
frameworks/Ruby/padrino/config/auto_tune.rb

@@ -0,0 +1,41 @@
+#!/usr/bin/env ruby
+# Instantiate about one process per X MiB of available memory, scaling up to as
+# close to MAX_THREADS as possible while observing an upper bound based on the
+# number of virtual/logical CPUs. If there are fewer processes than
+# MAX_THREADS, add threads per process to reach MAX_THREADS.
+require 'etc'
+
+KB_PER_WORKER = 128 * 1_024 # average of peak PSS of single-threaded processes (watch smem -k)
+MIN_WORKERS = 2
+MAX_WORKERS_PER_VCPU = 1.25 # virtual/logical
+MIN_THREADS_PER_WORKER = 1
+MAX_THREADS = Integer(ENV['MAX_CONCURRENCY'] || 8)
+
+def meminfo(arg)
+  File.open('/proc/meminfo') do |f|
+    f.each_line do |line|
+      key, value = line.split(/:\s+/)
+      return value.split(/\s+/).first.to_i if key == arg
+    end
+  end
+
+  fail "Unable to find `#{arg}' in /proc/meminfo!"
+end
+
+def auto_tune
+  avail_mem = meminfo('MemAvailable') * 0.8 - MAX_THREADS * 1_024
+
+  workers = [
+    [(1.0 * avail_mem / KB_PER_WORKER).floor, MIN_WORKERS].max,
+    (Etc.nprocessors * MAX_WORKERS_PER_VCPU).ceil
+  ].min
+
+  threads_per_worker = [
+    workers < MAX_THREADS ? (1.0 * MAX_THREADS / workers).ceil : -Float::INFINITY,
+    MIN_THREADS_PER_WORKER
+  ].max
+
+  [workers, threads_per_worker]
+end
+
+p auto_tune if $0 == __FILE__

+ 8 - 2
frameworks/Ruby/padrino/config/puma.rb

@@ -1,3 +1,9 @@
+require_relative 'auto_tune'
+
+num_workers, num_threads = auto_tune
+
+workers num_workers
+threads num_threads, num_threads
+
 environment 'production'
-threads 8, 32
-bind 'tcp://0.0.0.0:8080'
+bind 'tcp://0.0.0.0:8080'

+ 5 - 1
frameworks/Ruby/padrino/config/unicorn.rb

@@ -1,4 +1,8 @@
-worker_processes 8
+require_relative 'auto_tune'
+
+num_workers, = auto_tune
+
+worker_processes num_workers
 listen "/tmp/.sock", :backlog => 4096
 
 preload_app true