From 516bcabbf42d60db2ac989dce4c7187b2a1e5de9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 3 Mar 2015 13:07:14 +0100 Subject: [PATCH] Increase timeout for Git-over-HTTP requests. --- CHANGELOG | 1 + Gemfile | 3 +++ Gemfile.lock | 8 ++++++++ config/initializers/timeout.rb | 8 ++++++++ config/unicorn.rb.example | 20 ++++---------------- lib/gitlab/middleware/timeout.rb | 13 +++++++++++++ public/503.html | 13 +++++++++++++ 7 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 config/initializers/timeout.rb create mode 100644 lib/gitlab/middleware/timeout.rb create mode 100644 public/503.html diff --git a/CHANGELOG b/CHANGELOG index 6a28772097e..7985a811f11 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,7 @@ v 7.9.0 (unreleased) - Allow user confirmation to be skipped for new users via API - Add a service to send updates to an Irker gateway (Romain Coltel) - Add brakeman (security scanner for Ruby on Rails) + - Increase timeout for Git-over-HTTP requests to 1 hour since large pulls/pushes can take a long time. v 7.8.1 - Fix run of custom post receive hooks diff --git a/Gemfile b/Gemfile index 01c02b5c8db..f2517c6faa4 100644 --- a/Gemfile +++ b/Gemfile @@ -177,6 +177,9 @@ gem 'ace-rails-ap' # Keyboard shortcuts gem 'mousetrap-rails' +# Shutting down requests that take too long +gem "slowpoke" + gem "sass-rails", '~> 4.0.2' gem "coffee-rails" gem "uglifier" diff --git a/Gemfile.lock b/Gemfile.lock index 102d1a28875..7fde0011d38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -149,6 +149,7 @@ GEM enumerize (0.7.0) activesupport (>= 3.2) equalizer (0.0.8) + errbase (0.0.2) erubis (2.7.0) escape_utils (0.2.4) eventmachine (1.0.4) @@ -428,6 +429,7 @@ GEM rack rack-test (0.6.3) rack (>= 1.0) + rack-timeout (0.2.0) rails (4.1.9) actionmailer (= 4.1.9) actionpack (= 4.1.9) @@ -481,6 +483,8 @@ GEM rest-client (1.6.7) mime-types (>= 1.16) rinku (1.7.3) + robustly (0.0.3) + errbase rouge (1.7.4) rspec (2.99.0) rspec-core (~> 2.99.0) @@ -563,6 +567,9 @@ GEM temple (~> 0.6.6) tilt (>= 1.3.3, < 2.1) slop (3.6.0) + slowpoke (0.0.5) + rack-timeout (>= 0.1.0) + robustly spinach (0.8.7) colorize (= 0.5.8) gherkin-ruby (>= 0.3.1) @@ -772,6 +779,7 @@ DEPENDENCIES six slack-notifier (~> 1.0.0) slim + slowpoke spinach-rails spring (= 1.3.1) spring-commands-rspec (= 1.0.4) diff --git a/config/initializers/timeout.rb b/config/initializers/timeout.rb new file mode 100644 index 00000000000..bc88595cf26 --- /dev/null +++ b/config/initializers/timeout.rb @@ -0,0 +1,8 @@ +# Slowpoke extends Rack::Timeout to gracefully kill Unicorn workers so they can clean up state. +Slowpoke.timeout = 60 + +# The `Rack::Timeout` middleware kills requests after 60 seconds (as set above). +# We're replacing it with our `Gitlab::Middleware::Timeout` that does the same, +# except ignoring Git-over-HTTP requests, letting those take as long as they need. + +Rails.application.config.middleware.swap(Rack::Timeout, Gitlab::Middleware::Timeout) diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example index d8b4f5c7c32..29253b71f49 100644 --- a/config/unicorn.rb.example +++ b/config/unicorn.rb.example @@ -35,22 +35,10 @@ working_directory "/home/git/gitlab" # available in 0.94.0+ listen "/home/git/gitlab/tmp/sockets/gitlab.socket", :backlog => 1024 listen "127.0.0.1:8080", :tcp_nopush => true -# nuke workers after 30 seconds instead of 60 seconds (the default) -# -# NOTICE: git push over http depends on this value. -# If you want be able to push huge amount of data to git repository over http -# you will have to increase this value too. -# -# Example of output if you try to push 1GB repo to GitLab over http. -# -> git push http://gitlab.... master -# -# error: RPC failed; result=18, HTTP code = 200 -# fatal: The remote end hung up unexpectedly -# fatal: The remote end hung up unexpectedly -# -# For more information see http://stackoverflow.com/a/21682112/752049 -# -timeout 60 +# Kill workers after 1 hour. +# A shorter timeout of 60 seconds is enforced by rack-timeout for web requests. +# Git-over-HTTP only has the below timeout since large pulls/pushes can take a long time. +timeout 60 * 60 # feel free to point this anywhere accessible on the filesystem pid "/home/git/gitlab/tmp/pids/unicorn.pid" diff --git a/lib/gitlab/middleware/timeout.rb b/lib/gitlab/middleware/timeout.rb new file mode 100644 index 00000000000..015600392b9 --- /dev/null +++ b/lib/gitlab/middleware/timeout.rb @@ -0,0 +1,13 @@ +module Gitlab + module Middleware + class Timeout < Rack::Timeout + GRACK_REGEX = /[-\/\w\.]+\.git\//.freeze + + def call(env) + return @app.call(env) if env['PATH_INFO'] =~ GRACK_REGEX + + super + end + end + end +end diff --git a/public/503.html b/public/503.html new file mode 100644 index 00000000000..efdae0f512d --- /dev/null +++ b/public/503.html @@ -0,0 +1,13 @@ + + + + Page took too long to load (503) + + + +

503

+

Page took too long to load.

+
+

Please contact your GitLab administrator if this problem persists.

+ +