diff --git a/app/controllers/onebox_controller.rb b/app/controllers/onebox_controller.rb index 83f0efa96..474feb5fd 100644 --- a/app/controllers/onebox_controller.rb +++ b/app/controllers/onebox_controller.rb @@ -3,7 +3,7 @@ require_dependency 'oneboxer' class OneboxController < ApplicationController def show - result = Oneboxer.onebox(params[:url], invalidate_oneboxes: params[:refresh] == 'true') + result = Oneboxer.preview(params[:url], invalidate_oneboxes: params[:refresh] == 'true') result.strip! if result.present? # If there is no result, return a 404 diff --git a/lib/cooked_post_processor.rb b/lib/cooked_post_processor.rb index 94ccd5e92..2cfd7d165 100644 --- a/lib/cooked_post_processor.rb +++ b/lib/cooked_post_processor.rb @@ -24,7 +24,7 @@ class CookedPostProcessor args[:invalidate_oneboxes] = true if @opts[:invalidate_oneboxes] Oneboxer.each_onebox_link(@doc) do |url, element| - onebox = Oneboxer.onebox(url, args) + onebox, preview = Oneboxer.onebox(url, args) if onebox element.swap onebox @dirty = true diff --git a/lib/oneboxer.rb b/lib/oneboxer.rb index 82b0d5962..74a20bcac 100644 --- a/lib/oneboxer.rb +++ b/lib/oneboxer.rb @@ -84,23 +84,46 @@ module Oneboxer "onebox:#{Digest::SHA1.hexdigest(url)}" end + def self.preview_cache_key_for(url) + "onebox:preview:#{Digest::SHA1.hexdigest(url)}" + end + def self.render_from_cache(url) Rails.cache.read(cache_key_for(url)) end # Cache results from a onebox call def self.fetch_and_cache(url, args) - contents = onebox_nocache(url) + contents, preview = onebox_nocache(url) return nil if contents.blank? Rails.cache.write(cache_key_for(url), contents, expires_in: default_expiry) - contents + if preview.present? + Rails.cache.write(preview_cache_key_for(url), preview, expires_in: default_expiry) + end + + [contents, preview] end def self.invalidate(url) Rails.cache.delete(cache_key_for(url)) end + def self.preview(url, args={}) + # Look for a preview + cached = Rails.cache.read(preview_cache_key_for(url)) unless args[:no_cache].present? + return cached if cached.present? + + # Try the full version + cached = render_from_cache(url) + return cached if cached.present? + + # If that fails, look it up + contents, cached = fetch_and_cache(url, args) + return cached if cached.present? + contents + end + # Return the cooked content for a url, caching the result for performance def self.onebox(url, args={}) diff --git a/spec/controllers/onebox_controller_spec.rb b/spec/controllers/onebox_controller_spec.rb index 26bf29da4..94fda6fd4 100644 --- a/spec/controllers/onebox_controller_spec.rb +++ b/spec/controllers/onebox_controller_spec.rb @@ -5,7 +5,7 @@ describe OneboxController do let(:url) { "http://google.com" } it 'invalidates the cache if refresh is passed' do - Oneboxer.expects(:onebox).with(url, invalidate_oneboxes: true) + Oneboxer.expects(:preview).with(url, invalidate_oneboxes: true) xhr :get, :show, url: url, refresh: 'true' end @@ -14,7 +14,7 @@ describe OneboxController do let(:body) { "this is the onebox body"} before do - Oneboxer.expects(:onebox).with(url, invalidate_oneboxes: false).returns(body) + Oneboxer.expects(:preview).with(url, invalidate_oneboxes: false).returns(body) xhr :get, :show, url: url end @@ -31,13 +31,13 @@ describe OneboxController do describe "missing onebox" do it "returns 404 if the onebox is nil" do - Oneboxer.expects(:onebox).with(url, invalidate_oneboxes: false).returns(nil) + Oneboxer.expects(:preview).with(url, invalidate_oneboxes: false).returns(nil) xhr :get, :show, url: url response.response_code.should == 404 end it "returns 404 if the onebox is an empty string" do - Oneboxer.expects(:onebox).with(url, invalidate_oneboxes: false).returns(" \t ") + Oneboxer.expects(:preview).with(url, invalidate_oneboxes: false).returns(" \t ") xhr :get, :show, url: url response.response_code.should == 404 end