From 309d757e925f925f762fd3fbb0475d9db1e3d8d5 Mon Sep 17 00:00:00 2001 From: David Ortiz Date: Mon, 13 Jan 2020 14:48:08 +0100 Subject: [PATCH 1/3] Gemfiles: add falcon --- Gemfile.base | 1 + Gemfile.lock | 47 +++++++++++++++++++++++++++++++++++++++++--- Gemfile.on_prem.lock | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/Gemfile.base b/Gemfile.base index c933f4a04..63da55c4c 100644 --- a/Gemfile.base +++ b/Gemfile.base @@ -63,3 +63,4 @@ gem 'bugsnag', '~> 6', require: nil gem 'prometheus-client' gem 'yabeda-prometheus', '= 0.1.4' gem 'async-redis', '~> 0.4.1' +gem 'falcon', '~> 0.34' diff --git a/Gemfile.lock b/Gemfile.lock index 1d0341dd1..28139d62b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,12 +41,25 @@ GEM airbrake (4.3.1) builder multi_json - async (1.22.0) + async (1.24.1) console (~> 1.0) nio4r (~> 2.3) timers (~> 4.1) - async-io (1.25.0) + async-container (0.14.1) + async (~> 1.0) + async-io (~> 1.4) + process-group + async-http (0.50.0) + async (~> 1.23) + async-io (~> 1.27.0) + async-pool (~> 0.2) + protocol-http (~> 0.13.0) + protocol-http1 (~> 0.10.0) + protocol-http2 (~> 0.10.0) + async-io (1.27.1) async (~> 1.14) + async-pool (0.2.0) + async (~> 1.8) async-redis (0.4.1) async (~> 1.8) async-io (~> 1.10) @@ -65,6 +78,7 @@ GEM benchmark-ips (2.7.2) bugsnag (6.6.4) concurrent-ruby (~> 1.0) + build-environment (1.12.1) builder (3.2.3) byebug (9.1.0) chronic (0.10.2) @@ -72,13 +86,23 @@ GEM simplecov (>= 0.7.1, < 1.0.0) coderay (1.1.2) concurrent-ruby (1.0.5) - console (1.4.0) + console (1.7.0) daemons (1.2.4) diff-lcs (1.3) docile (1.1.5) dry-initializer (3.0.1) + falcon (0.34.5) + async (~> 1.13) + async-container (~> 0.14.0) + async-http (~> 0.50.0) + async-io (~> 1.22) + build-environment (~> 1.11) + localhost (~> 1.1) + rack (>= 1.0) + samovar (~> 2.1) faraday (0.13.1) multipart-post (>= 1.2, < 3) + ffi (1.11.3) geminabox (0.13.11) builder faraday @@ -100,6 +124,8 @@ GEM toml (= 0.2.0) with_env (= 1.1.0) xml-simple + localhost (1.1.6) + mapping (1.1.1) metaclass (0.0.4) method_source (0.9.0) mini_portile2 (2.4.0) @@ -122,8 +148,19 @@ GEM pg (0.20.0) pkg-config (1.1.9) power_assert (1.1.1) + process-group (1.2.1) + process-terminal (~> 0.2.0) + process-terminal (0.2.0) + ffi prometheus-client (0.9.0) quantile (~> 0.2.1) + protocol-hpack (1.4.1) + protocol-http (0.13.0) + protocol-http1 (0.10.0) + protocol-http (~> 0.13) + protocol-http2 (0.10.4) + protocol-hpack (~> 1.4) + protocol-http (~> 0.2) protocol-redis (0.2.0) pry (0.11.3) coderay (~> 1.1.0) @@ -174,6 +211,9 @@ GEM mustache (~> 1.0, >= 0.99.4) rspec (~> 3.0) rubyzip (2.0.0) + samovar (2.1.2) + console (~> 1.0) + mapping (~> 1.0) scientist (1.0.0) simplecov (0.15.1) docile (~> 1.1.0) @@ -236,6 +276,7 @@ DEPENDENCIES builder (= 3.2.3) codeclimate-test-reporter (~> 0.6.0) daemons (= 1.2.4) + falcon (~> 0.34) geminabox (~> 0.13.11) gli (~> 2.16.1) hiredis (= 0.6.1) diff --git a/Gemfile.on_prem.lock b/Gemfile.on_prem.lock index 7d6cacd9e..c3e410542 100644 --- a/Gemfile.on_prem.lock +++ b/Gemfile.on_prem.lock @@ -42,6 +42,16 @@ GEM console (~> 1.0) nio4r (~> 2.3) timers (~> 4.1) + async-container (0.14.1) + async (~> 1.0) + async-io (~> 1.4) + process-group + async-http (0.48.2) + async (~> 1.19) + async-io (~> 1.25) + protocol-http (~> 0.12.0) + protocol-http1 (~> 0.9.0) + protocol-http2 (~> 0.9.0) async-io (1.25.0) async (~> 1.14) async-redis (0.4.1) @@ -56,6 +66,7 @@ GEM benchmark-ips (2.7.2) bugsnag (6.6.4) concurrent-ruby (~> 1.0) + build-environment (1.12.1) builder (3.2.3) byebug (9.1.0) codeclimate-test-reporter (0.6.0) @@ -67,8 +78,18 @@ GEM diff-lcs (1.3) docile (1.1.5) dry-initializer (3.0.1) + falcon (0.34.3) + async (~> 1.13) + async-container (~> 0.14.0) + async-http (~> 0.48.0) + async-io (~> 1.22) + build-environment (~> 1.11) + localhost (~> 1.1) + rack (>= 1.0) + samovar (~> 2.1) faraday (0.13.1) multipart-post (>= 1.2, < 3) + ffi (1.11.3) geminabox (0.13.11) builder faraday @@ -89,6 +110,8 @@ GEM toml (= 0.2.0) with_env (= 1.1.0) xml-simple + localhost (1.1.6) + mapping (1.1.1) metaclass (0.0.4) method_source (0.9.0) mini_portile2 (2.4.0) @@ -110,8 +133,19 @@ GEM parslet (1.8.2) pkg-config (1.1.9) power_assert (1.1.1) + process-group (1.2.1) + process-terminal (~> 0.2.0) + process-terminal (0.2.0) + ffi prometheus-client (0.9.0) quantile (~> 0.2.1) + protocol-hpack (1.4.1) + protocol-http (0.12.3) + protocol-http1 (0.9.0) + protocol-http (~> 0.5) + protocol-http2 (0.9.7) + protocol-hpack (~> 1.4) + protocol-http (~> 0.2) protocol-redis (0.2.0) pry (0.11.3) coderay (~> 1.1.0) @@ -162,6 +196,9 @@ GEM mustache (~> 1.0, >= 0.99.4) rspec (~> 3.0) rubyzip (2.0.0) + samovar (2.1.2) + console (~> 1.0) + mapping (~> 1.0) simplecov (0.15.1) docile (~> 1.1.0) json (>= 1.8, < 3) @@ -218,6 +255,7 @@ DEPENDENCIES builder (= 3.2.3) codeclimate-test-reporter (~> 0.6.0) daemons (= 1.2.4) + falcon (~> 0.34) geminabox (~> 0.13.11) gli (~> 2.16.1) hiredis (= 0.6.1) From a11710dc6f3c26d50330834ea8c6f438d07405f4 Mon Sep 17 00:00:00 2001 From: David Ortiz Date: Mon, 13 Jan 2020 17:42:51 +0100 Subject: [PATCH 2/3] server: add Falcon --- lib/3scale/backend/server/falcon.rb | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 lib/3scale/backend/server/falcon.rb diff --git a/lib/3scale/backend/server/falcon.rb b/lib/3scale/backend/server/falcon.rb new file mode 100644 index 000000000..3834c068c --- /dev/null +++ b/lib/3scale/backend/server/falcon.rb @@ -0,0 +1,48 @@ +module ThreeScale + module Backend + module Server + class Falcon + extend ThreeScale::Backend::Server::Utils + + def self.start(global_options, options, args) + # Falcon does not support: + # - options[:daemonize] + # - options[:logfile] + # - options[:errorfile] + # - options[:pidfile] + + manifest = global_options[:manifest] + return unless manifest + + argv = ['falcon'] + argv_add argv, true, '--bind', 'http://0.0.0.0' + argv_add argv, options[:port], '--port', options[:port] + + server_model = manifest[:server_model] + argv_add argv, true, '--count', server_model[:workers].to_s + end + + def self.restart(global_options, options, args) + argv = ['falcon', 'supervisor'] + argv_add argv, true, 'restart' + end + + def self.stop(global_options, options, args) + STDERR.puts 'Not implemented' + end + + def self.status(global_options, options, args) + STDERR.puts 'Not implemented' + end + + def self.stats(global_options, options, args) + STDERR.puts 'Not implemented' + end + + def self.help(global_options, options, args) + system('falcon --help') + end + end + end + end +end From 1dd6d143a3d7922004ec34e8a7410a30000d4aa4 Mon Sep 17 00:00:00 2001 From: David Ortiz Date: Thu, 23 Jan 2020 14:58:11 +0100 Subject: [PATCH 3/3] manifest: decide workers based on LISTENER_WORKERS --- lib/3scale/backend/manifest.rb | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/3scale/backend/manifest.rb b/lib/3scale/backend/manifest.rb index 90d4f6a45..525460a2c 100644 --- a/lib/3scale/backend/manifest.rb +++ b/lib/3scale/backend/manifest.rb @@ -6,6 +6,8 @@ module ThreeScale module Backend module Manifest class << self + LISTENER_WORKERS = 'LISTENER_WORKERS'.freeze + private_constant :LISTENER_WORKERS PUMA_WORKERS = 'PUMA_WORKERS'.freeze private_constant :PUMA_WORKERS PUMA_WORKERS_CPUMULT = 8 @@ -16,19 +18,15 @@ def thread_safe? false end - # Compute workers based on PUMA_WORKERS env variable - # If PUMA_WORKERS does not exist or is empty, use number of cpus + # Compute workers based on LISTENER_WORKERS and PUMA_WORKERS env + # variables. The former takes precedence. + # If those envs do not exist or are empty, use number of cpus def compute_workers(ncpus) return 0 unless Process.respond_to?(:fork) - if ENV[PUMA_WORKERS] && !ENV[PUMA_WORKERS].empty? - begin - Integer(ENV[PUMA_WORKERS]) - rescue => e - raise e, "PUMA_WORKERS environment var cannot be parsed: #{e.message}" - end - else + + compute_workers_from_env(LISTENER_WORKERS) || + compute_workers_from_env(PUMA_WORKERS) || ncpus * PUMA_WORKERS_CPUMULT - end end def server_model @@ -64,6 +62,18 @@ def report server_model: server_model, } end + + private + + def compute_workers_from_env(env_name) + if ENV[env_name] && !ENV[env_name].empty? + begin + Integer(ENV[env_name]) + rescue => e + raise e, "#{env_name} environment var cannot be parsed: #{e.message}" + end + end + end end end end