From 5e2b8d087c868107e6013f1745a09b0c1dffa4e9 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 19 Jul 2010 18:01:42 +0100 Subject: [PATCH] Make memory limits configurable and make them work with passenger --- config/application.yml | 5 +++- config/initializers/limits.rb | 4 --- config/initializers/memory_limits.rb | 44 ++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) delete mode 100644 config/initializers/limits.rb create mode 100644 config/initializers/memory_limits.rb diff --git a/config/application.yml b/config/application.yml index 1b38f8f74..95037f83e 100644 --- a/config/application.yml +++ b/config/application.yml @@ -28,7 +28,10 @@ standard_settings: &standard_settings spam_threshold: 50 # Default legale (jurisdiction location) for contributor terms default_legale: GB - + # Memory limits (in Mb) + #soft_memory_limit: 512 + #hard_memory_limit: 2048 + development: <<: *standard_settings diff --git a/config/initializers/limits.rb b/config/initializers/limits.rb deleted file mode 100644 index 9862036f7..000000000 --- a/config/initializers/limits.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Set a hard limit of 1Gb on the virtual size of the process -if Process.const_defined?(:RLIMIT_AS) - Process.setrlimit Process::RLIMIT_AS, 1024*1024*1024, Process::RLIM_INFINITY -end diff --git a/config/initializers/memory_limits.rb b/config/initializers/memory_limits.rb new file mode 100644 index 000000000..bab94b09a --- /dev/null +++ b/config/initializers/memory_limits.rb @@ -0,0 +1,44 @@ +# Setup any specified hard limit on the virtual size of the process +if APP_CONFIG.include?('hard_memory_limit') and Process.const_defined?(:RLIMIT_AS) + Process.setrlimit Process::RLIMIT_AS, APP_CONFIG['hard_memory_limit']*1024*1024, Process::RLIM_INFINITY +end + +# If we're running under passenger and a soft memory limit is +# configured then setup some rack middleware to police the limit +if APP_CONFIG.include?('soft_memory_limit') and defined?(PhusionPassenger) + # Define some rack middleware to police the soft memory limit + module OSM + class MemoryLimit + def initialize(app) + @app = app + end + + def call(env) + # Process this requst + status, headers, body = @app.call(env) + + # Restart if we've hit our memory limit + if resident_size > APP_CONFIG['soft_memory_limit'] + Process.kill("USR1", 0) + end + + # Return the result of this request + [status, headers, body] + end + private + def resident_size + # Read statm to get process sizes. Format is + # Size RSS Shared Text Lib Data + fields = File.open("/proc/self/statm") do |file| + fields = file.gets.split(" ") + end + + # Return resident size in megabytes + return fields[1].to_i / 256 + end + end + end + + # Install the memory limit checker + Rails.configuration.middleware.use OSM::MemoryLimit +end -- 2.43.2