introduce rack:cache as a default, so users don't need to configure apache or nginx

under rack cache we are able to serve 620reqs a second per thin (on my machine) before it 12 (on my machine)

reorganised so mini profilers can be cleanly disabled from config file

added caching for categories index

move production.rb to production.sample.rb
This commit is contained in:
Sam 2013-04-11 16:24:08 +10:00
parent edd25e01a8
commit 850b042cab
16 changed files with 100 additions and 64 deletions

View file

@ -112,8 +112,12 @@ gem 'fast_blank' #, github: "SamSaffron/fast_blank"
# IMPORTANT: mini profiler monkey patches, so it better be required last
# If you want to amend mini profiler to do the monkey patches in the railstie
# we are open to it.
gem 'rack-mini-profiler' #, git: 'git://github.com/SamSaffron/MiniProfiler'
# we are open to it. by deferring require to the initializer we can configure disourse installs without it
gem 'rack-mini-profiler', require: false # require: false #, git: 'git://github.com/SamSaffron/MiniProfiler'
# used for caching, optional
gem 'redis-rack-cache', require: false
gem 'rack-cache', require: false
# perftools only works on 1.9 atm
group :profile do

View file

@ -319,7 +319,7 @@ GEM
rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
rack-mini-profiler (0.1.25)
rack-mini-profiler (0.1.26)
rack (>= 1.1.3)
rack-openid (1.3.1)
rack (>= 1.1.0)
@ -367,6 +367,9 @@ GEM
redis-rack (1.4.2)
rack (~> 1.4.1)
redis-store (~> 1.1.0)
redis-rack-cache (1.2.1)
rack-cache (~> 1.2)
redis-store (~> 1.1.0)
redis-rails (3.2.3)
redis-actionpack (~> 3.2.3)
redis-activesupport (~> 3.2.3)
@ -514,6 +517,7 @@ DEPENDENCIES
openid-redis-store
pg
pry-rails
rack-cache
rack-mini-profiler
rails
rails_multisite!
@ -522,6 +526,7 @@ DEPENDENCIES
rb-inotify (~> 0.8.8)
redcarpet
redis
redis-rack-cache
redis-rails
rest-client
rinku

View file

@ -140,7 +140,7 @@ class ApplicationController < ActionController::Base
def can_cache_content?
# Don't cache unless we're in production mode
return false unless Rails.env.production?
return false unless Rails.env.production? || Rails.env == "profile"
# Don't cache logged in users
return false if current_user.present?

View file

@ -6,6 +6,7 @@ class CategoriesController < ApplicationController
def index
list = CategoryList.new(current_user)
discourse_expires_in 1.minute
render_serialized(list, CategoryListSerializer)
end

View file

@ -16,21 +16,11 @@
<%# load the selected locale before any other scripts %>
<%= javascript_include_tag "locales/#{I18n.locale}" %>
<%- if mini_profiler_enabled? %>
<%- Rack::MiniProfiler.step "application" do %>
<%= javascript_include_tag "application" %>
<%-end%>
<%- Rack::MiniProfiler.step "admin" do %>
<%= javascript_include_tag "admin"%>
<%-end%>
<%- else %>
<%= javascript_include_tag "application" %>
<%- if admin? %>
<%= javascript_include_tag "admin"%>
<%- end %>
<%- end%>
<%= javascript_include_tag "application" %>
<%= javascript_include_tag "admin"%>
<%- if admin? %>
<%= javascript_include_tag "admin"%>
<%- end %>
<script>
Discourse.CDN = '<%= Rails.configuration.action_controller.asset_host %>';

View file

@ -1,12 +1,8 @@
<%- unless SiteCustomization.override_default_style(session[:preview_style]) %>
<%=stylesheet_link_tag "application"%>
<%- end %>
<%- unless SiteCustomization.override_default_style(session[:preview_style]) %>
<%=stylesheet_link_tag "application"%>
<%- end %>
<%- if mini_profiler_enabled? %>
<%- Rack::MiniProfiler.step "stylsheet" do%>
<%= stylesheet_link_tag "admin"%>
<%-end%>
<%- elsif admin? %>
<%= stylesheet_link_tag "admin"%>
<%-end%>
<%=SiteCustomization.custom_stylesheet(session[:preview_style])%>
<%- if admin? %>
<%= stylesheet_link_tag "admin"%>
<%-end%>
<%=SiteCustomization.custom_stylesheet(session[:preview_style])%>

View file

@ -8,21 +8,9 @@
<meta content="" name="author">
<link rel="icon" type="image/png" href=<%=SiteSetting.favicon_url%>>
<%- if mini_profiler_enabled? %>
<%- Rack::MiniProfiler.step "stylsheet" do%>
<%=stylesheet_link_tag "application"%>
<%- end %>
<%- if current_user.try(:admin) %>
<%- Rack::MiniProfiler.step "stylsheet" do%>
<%= stylesheet_link_tag "admin"%>
<%-end%>
<%- end %>
<%- else %>
<%=stylesheet_link_tag "application"%>
<%- if current_user.try(:admin) %>
<%= stylesheet_link_tag "admin"%>
<%- end %>
<%=stylesheet_link_tag "application"%>
<%- if current_user.try(:admin) %>
<%= stylesheet_link_tag "admin"%>
<%- end %>
<%=csrf_meta_tags%>

View file

@ -92,9 +92,15 @@ module Discourse
# Use redis for our cache
config.cache_store = DiscourseRedis.new_redis_store
# Test with rack::cache disabled. Nginx does this for us
# we configure rack cache on demand in an initializer
# our setup does not use rack cache and instead defers to nginx
config.action_dispatch.rack_cache = nil
# ember stuff only used for asset precompliation, production variant plays up
config.ember.variant = :development
config.ember.ember_location = "#{Rails.root}/app/assets/javascripts/external_production/ember.js"
config.ember.handlebars_location = "#{Rails.root}/app/assets/javascripts/external/handlebars-1.0.rc.3.js"
# So open id logs somewhere sane
config.after_initialize do
OpenID::Util.logger = Rails.logger

View file

@ -29,15 +29,15 @@ Discourse::Application.configure do
config.watchable_dirs['lib'] = [:rb]
config.sass.debug_info = false
config.ember.variant = :development
config.ember.handlebars_location = "#{Rails.root}/app/assets/javascripts/external/handlebars-1.0.rc.3.js"
config.ember.ember_location = "#{Rails.root}/app/assets/javascripts/external/ember.js"
config.handlebars.precompile = false
# we recommend you use mailcatcher https://github.com/sj26/mailcatcher
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { address: "localhost", port: 1025 }
config.action_mailer.raise_delivery_errors = true
BetterErrors::Middleware.allow_ip! ENV['TRUSTED_IP'] if ENV['TRUSTED_IP']
config.enable_mini_profiler = true
end

View file

@ -27,17 +27,32 @@ Discourse::Application.configure do
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
# you may use other configuration here for mail eg: sendgrid
# config.action_mailer.delivery_method = :smtp
# config.action_mailer.smtp_settings = {
# :address => "smtp.sendgrid.net",
# :port => 587,
# :domain => 'YOUR DOMAIN',
# :user_name => 'YOUR_USER',
# :password => 'YOUR_PASSWORD',
# :authentication => 'plain',
# :enable_starttls_auto => true }
config.action_mailer.delivery_method = :sendmail
config.action_mailer.sendmail_settings = {arguments: '-i'}
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
# I dunno ... perhaps the built-in minifier is using closure
# regardless it is blowing up
config.ember.variant = :development
config.ember.ember_location = "#{Rails.root}/app/assets/javascripts/external_production/ember.js"
config.ember.handlebars_location = "#{Rails.root}/app/assets/javascripts/external/handlebars-1.0.rc.3.js"
# this will cause all handlebars templates to be pre-compiles, making your page faster
config.handlebars.precompile = true
# this setting enables rack_cache so it caches various requests in redis
config.enable_rack_cache = true
# allows admins to use mini profiler
config.enable_mini_profiler = true
end

View file

@ -33,13 +33,15 @@ Discourse::Application.configure do
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
# I dunno ... perhaps the built-in minifier is using closure
# regardless it is blowing up
config.ember.variant = :development
config.ember.ember_location = "#{Rails.root}/app/assets/javascripts/external_production/ember.js"
config.ember.handlebars_location = "#{Rails.root}/app/assets/javascripts/external/handlebars-1.0.rc.3.js"
# precompile handlebar assets
config.handlebars.precompile = true
# config.middleware.use ::Rack::PerftoolsProfiler, default_printer: 'gif'
# this setting enable rack_cache so it caches various requests in redis
config.enable_rack_cache = false
# allows users to use mini profiler
config.enable_mini_profiler = false
# for profiling with perftools
# config.middleware.use ::Rack::PerftoolsProfiler, default_printer: 'gif'
end

View file

@ -1,4 +1,10 @@
# If Mini Profiler is included via gem
if Rails.configuration.respond_to?(:enable_mini_profiler) && Rails.configuration.enable_mini_profiler
require 'rack-mini-profiler'
# initialization is skipped so trigger it
Rack::MiniProfilerRails.initialize!(Rails.application)
end
if defined?(Rack::MiniProfiler)
# note, we may want to add some extra security here that disables mini profiler in a multi hosted env unless user global admin

View file

@ -0,0 +1,11 @@
if Rails.configuration.respond_to?(:enable_rack_cache) && Rails.configuration.enable_rack_cache
require 'rack-cache'
require 'redis-rack-cache'
url = DiscourseRedis.url
Rails.configuration.middleware.insert 0, Rack::Cache,
metastore: "#{url}/metastore",
entitystore: "#{url}/entitystore",
verbose: !Rails.env.production?
end

View file

@ -1,5 +1,11 @@
module CurrentUser
def self.has_auth_cookie?(env)
request = Rack::Request.new(env)
cookie = request.cookies["_t"]
!cookie.nil? && cookie.length == 32
end
def self.lookup_from_env(env)
request = Rack::Request.new(env)
lookup_from_auth_token(request.cookies["_t"])

View file

@ -11,7 +11,12 @@ class DiscourseRedis
end
def self.config
YAML.load(ERB.new(File.new("#{Rails.root}/config/redis.yml").read).result)[Rails.env]
@config ||= YAML.load(ERB.new(File.new("#{Rails.root}/config/redis.yml").read).result)[Rails.env]
end
def self.url(config=nil)
config ||= self.config
"redis://#{(':' + config['password'] + '@') if config['password']}#{config['host']}:#{config['port']}/#{config['db']}"
end
def initialize
@ -19,6 +24,10 @@ class DiscourseRedis
@redis = DiscourseRedis.raw_connection(@config)
end
def url
self.class.url(@config)
end
# prefix the key with the namespace
def method_missing(meth, *args, &block)
if @redis.respond_to?(meth)
@ -52,8 +61,5 @@ class DiscourseRedis
redis_store
end
def url
"redis://#{(':' + @config['password'] + '@') if @config['password']}#{@config['host']}:#{@config['port']}/#{@config['db']}"
end
end