Permalink
Browse files

add a recovery mode that will allow the site to continue operating wi…

…thout Redis
  • Loading branch information...
1 parent a9989f8 commit 4c8d57f8ba5c248a6cbc030e6493cdf6c38e5892 @qrush qrush committed Aug 17, 2012
View
@@ -64,6 +64,10 @@ group :development, :test, :staging, :production do
gem 'newrelic-redis'
end
+group :recovery do
+ gem "fakeredis"
+end
+
platforms :jruby do
gem 'jruby-openssl'
end
View
@@ -84,6 +84,8 @@ GEM
factory_girl_rails (4.0.0)
factory_girl (~> 4.0.0)
railties (>= 3.0.0)
+ fakeredis (0.4.0)
+ redis (~> 3.0.0)
ffi (1.1.5)
fog (1.4.0)
builder
@@ -238,6 +240,7 @@ DEPENDENCIES
dynamic_form
excon
factory_girl_rails
+ fakeredis
fog (~> 1.4.0)
gchartrb
gravtastic
@@ -73,7 +73,7 @@ def serve_via_cf
content_type('application/x-deflate')
serve_via_cf
else
- error 404, "This gem does not currently live at Gemcutter."
+ error 404, "This gem does not currently live at RubyGems.org."
end
end
@@ -86,7 +86,7 @@ def serve_via_cf
serve_via_cf
else
- error 404, "This gem does not currently live at Gemcutter."
+ error 404, "This gem does not currently live at RubyGems.org."
end
end
end
@@ -25,6 +25,6 @@ def call(env)
private
def redirect_to(url)
- [301, {"Location" => url}, []]
+ [301, {"Location" => url}, []]
end
end
@@ -50,7 +50,7 @@
<ol>
<% current_user.subscribed_gems.each do |gem| %>
<li>
- <%= download_count(gem) %>
+ <%= download_count(gem) unless Rails.env.recovery? %>
<%= link_to gem, gem, :title => short_info(gem.versions.most_recent) %>
</li>
<% end %>
@@ -1,7 +1,9 @@
<% content_for :fold do %>
<div class="count">
- <strong><%= t 'download_count', :count => number_with_delimiter(@downloads_count) %></strong>
- <%= t '.gems_header', :gem_count => number_with_delimiter(@rubygems_count) %>
+ <% unless Rails.env.recovery? %>
+ <strong><%= t 'download_count', :count => number_with_delimiter(@downloads_count) %></strong>
+ <%= t '.gems_header', :gem_count => number_with_delimiter(@rubygems_count) %>
+ <% end %>
</div>
<div class="blurb">
<strong><%= t '.welcome_blurb' %></strong>
@@ -56,16 +58,16 @@
</div>
<div class="grid_3" id="most_downloaded">
<strong><%= t '.leaderboards.downloaded' %></strong>
- <% if @downloaded.any? %>
+ <% if Rails.env.recovery? || @downloaded.none? %>
+ <p><%= t '.leaderboards.no_downloaded' %></p>
+ <% else %>
<ol>
<% @downloaded.each do |version, downloads| %>
<li>
<%= link_to "#{version.rubygem.name}-#{version.number} (#{number_with_delimiter downloads})", version.rubygem, :title => short_info(version) %>
</li>
<% end %>
</ol>
- <% else %>
- <p><%= t '.leaderboards.no_downloaded' %></p>
<% end %>
</div>
<div class="grid_3" id="just_updated">
@@ -3,12 +3,14 @@
<%= rubygem.name %>
<em><%= rubygem.versions.most_recent %></em>
</a>
- <a href="<%= rubygem_stats_path(rubygem) %>" class="profile-downloads">
- <div><%= t('download_count', :count => content_tag(:span, number_with_delimiter(rubygem.downloads))).html_safe %></div>
- <div><%= t('stats.show.daily_downloads', :count => content_tag(:span, number_with_delimiter(rubygem.downloads_today))).html_safe %></div>
- </a>
- <% if graph %>
- <div id="graph-<%= rubygem.id %>" class="profile-graph">
- </div>
+ <% unless Rails.env.recovery? %>
+ <a href="<%= rubygem_stats_path(rubygem) %>" class="profile-downloads">
+ <div><%= t('download_count', :count => content_tag(:span, number_with_delimiter(rubygem.downloads))).html_safe %></div>
+ <div><%= t('stats.show.daily_downloads', :count => content_tag(:span, number_with_delimiter(rubygem.downloads_today))).html_safe %></div>
+ </a>
+ <% if graph %>
+ <div id="graph-<%= rubygem.id %>" class="profile-graph">
+ </div>
+ <% end %>
<% end %>
</li>
@@ -10,11 +10,13 @@
<% if @user == current_user %>
<%= link_to "Edit Profile", edit_profile_path, :id => "edit-profile" %>
<% end %>
- <h5 id="downloads">Downloads</h5>
- <div id="downloads_count">
- <div><strong><%= number_with_delimiter(@user.today_downloads_count) %></strong> today</div>
- <div><strong><%= number_with_delimiter(@user.total_downloads_count) %></strong> all time</div>
- </div>
+ <% unless Rails.env.recovery? %>
+ <h5 id="downloads">Downloads</h5>
+ <div id="downloads_count">
+ <div><strong><%= number_with_delimiter(@user.today_downloads_count) %></strong> today</div>
+ <div><strong><%= number_with_delimiter(@user.total_downloads_count) %></strong> all time</div>
+ </div>
+ <% end %>
</div>
<% end %>
@@ -50,8 +52,12 @@
<div id="profile">
<div class="profile-list">
<ol>
- <%= render :partial => 'rubygem', :collection => @rubygems, :locals => {:graph => true} %>
- <%= render :partial => 'rubygem', :collection => @extra_rubygems, :locals => {:graph => false} %>
+ <% if Rails.env.recovery? %>
+ <%= render :partial => 'rubygem', :collection => @rubygems + @extra_rubygems, :locals => {:graph => false} %>
+ <% else %>
+ <%= render :partial => 'rubygem', :collection => @rubygems, :locals => {:graph => true} %>
+ <%= render :partial => 'rubygem', :collection => @extra_rubygems, :locals => {:graph => false} %>
+ <% end %>
</ol>
</div>
</div>
@@ -39,14 +39,16 @@
<% end %>
</div>
- <div class="downloads counter" data-href="<%= api_v1_download_path(@latest_version.full_name, :format => 'json') %>">
- <span>
- <%= t('stats.show.total_downloads', :count => content_tag(:strong, number_with_delimiter(@rubygem.downloads))).html_safe %>
- </span>
- <span>
- <%= t('.downloads_for_this_version', :count => content_tag(:strong, number_with_delimiter(@latest_version.downloads_count))).html_safe %>
- </span>
- </div>
+ <% unless Rails.env.recovery? %>
+ <div class="downloads counter" data-href="<%= api_v1_download_path(@latest_version.full_name, :format => 'json') %>">
+ <span>
+ <%= t('stats.show.total_downloads', :count => content_tag(:strong, number_with_delimiter(@rubygem.downloads))).html_safe %>
+ </span>
+ <span>
+ <%= t('.downloads_for_this_version', :count => content_tag(:strong, number_with_delimiter(@latest_version.downloads_count))).html_safe %>
+ </span>
+ </div>
+ <% end %>
<% if @rubygem.owners.present? %>
<div class="owners">
View
@@ -24,7 +24,7 @@ class Application < Rails::Application
config.encoding = "utf-8"
config.middleware.use "Hostess"
- config.middleware.insert_after "Hostess", "Redirector" if $rubygems_config[:redirector]
+ config.middleware.insert_after "Hostess", "Redirector" if $rubygems_config[:redirector] && ENV["LOCAL"].nil?
unless Rails.env.maintenance?
config.action_mailer.default_url_options = { :host => HOST }
@@ -0,0 +1,29 @@
+Gemcutter::Application.configure do
+ # for testing recovery mode on your local machine, LOCAL=1 rails s -e recovery
+ if ENV["LOCAL"]
+ config.cache_classes = false
+ config.whiny_nils = true
+
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+ config.active_support.deprecation = :log
+ config.action_mailer.raise_delivery_errors = false
+ else
+ config.cache_classes = true
+ config.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
+ config.action_dispatch.x_sendfile_header = "X-Sendfile"
+ config.active_support.deprecation = :notify
+ config.serve_static_assets = $rubygems_config[:asset_cacher]
+ config.i18n.fallbacks = true
+
+ config.action_dispatch.session = {
+ :domain => ".rubygems.org",
+ :secure => true
+ }
+ end
+
+ config.middleware.insert_after "Hostess", "RecoveryMode"
+end
+
+require Rails.root.join("config", "secret") if Rails.root.join("config", "secret.rb").file?
@@ -1,6 +1,7 @@
unless Rails.env.maintenance?
- Delayed::Job.const_set('MAX_ATTEMPTS', 3)
- Delayed::Job.const_set('MAX_RUN_TIME', 5.minutes)
+ require 'delayed_job'
+ Delayed::Worker.max_attempts = 3
+ Delayed::Worker.max_run_time = 5.minutes
end
PRIORITIES = {
@@ -1,5 +1,8 @@
if Rails.env.test? || Rails.env.cucumber?
$redis = Redis.new(:db => 1)
+elsif Rails.env.recovery?
+ require "fakeredis"
+ $redis = Redis.new
else
$redis = Redis.connect(:url => ENV['REDISTOGO_URL'])
end
@@ -6,3 +6,4 @@
require 'patterns'
require 'active_support/builder'
require 'rack/rewindable_input'
+require 'recovery_mode'
View
@@ -90,13 +90,13 @@
resource :dashboard, :only => :show
resources :profiles, :only => :show
resource :profile, :only => [:edit, :update]
- resources :stats, :only => :index
+ resources :stats, :only => :index, :constraints => RecoveryMode
resources :rubygems, :only => :index, :path => 'gems' do
constraints :rubygem_id => Patterns::ROUTE_PATTERN do
resource :subscription, :only => [:create, :destroy]
resources :versions, :only => :index
- resource :stats, :only => :show
+ resource :stats, :only => :show, :constraints => RecoveryMode
end
end
@@ -105,7 +105,7 @@
constraints :rubygem_id => Patterns::ROUTE_PATTERN do
resources :versions, :only => :show do
- resource :stats, :only => :show
+ resource :stats, :only => :show, :constraints => RecoveryMode
end
end
end
View
@@ -44,3 +44,7 @@ production:
maintenance:
delivery_method: :test
<<: *LIVE
+
+recovery:
+ delivery_method: :sendmail
+ <<: *LIVE
View
@@ -0,0 +1,19 @@
+class RecoveryMode
+ def self.matches?(request)
+ !Rails.env.recovery?
+ end
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ request = Rack::Request.new(env)
+
+ if request.path.starts_with?("/api/v1")
+ [503, {"Content-Type" => "text/plain"}, ["RubyGems.org's API is currently recovering. Check out http://status.rubygems.org and @rubygems_status for more info."]]
+ else
+ @app.call(env)
+ end
+ end
+end
Binary file not shown.

0 comments on commit 4c8d57f

Please sign in to comment.