From 0e95886a2e2b41c210b1bddea17fd052679804d0 Mon Sep 17 00:00:00 2001 From: Petrik Date: Sun, 5 Nov 2023 13:13:01 +0100 Subject: [PATCH] [ruby/padrino] Use auto_tune.rb for Puma and Unicorn config 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. --- frameworks/Ruby/padrino/config/auto_tune.rb | 41 +++++++++++++++++++++ frameworks/Ruby/padrino/config/puma.rb | 10 ++++- frameworks/Ruby/padrino/config/unicorn.rb | 6 ++- 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 frameworks/Ruby/padrino/config/auto_tune.rb diff --git a/frameworks/Ruby/padrino/config/auto_tune.rb b/frameworks/Ruby/padrino/config/auto_tune.rb new file mode 100644 index 00000000000..4544231b9d2 --- /dev/null +++ b/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__ diff --git a/frameworks/Ruby/padrino/config/puma.rb b/frameworks/Ruby/padrino/config/puma.rb index a4adcc8ded8..8a42642fd61 100644 --- a/frameworks/Ruby/padrino/config/puma.rb +++ b/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' \ No newline at end of file +bind 'tcp://0.0.0.0:8080' diff --git a/frameworks/Ruby/padrino/config/unicorn.rb b/frameworks/Ruby/padrino/config/unicorn.rb index fa84460c73d..9ca3171328b 100644 --- a/frameworks/Ruby/padrino/config/unicorn.rb +++ b/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