diff --git a/ubiquo_design/app/models/page.rb b/ubiquo_design/app/models/page.rb
index 9a93189b..9befb1b8 100644
--- a/ubiquo_design/app/models/page.rb
+++ b/ubiquo_design/app/models/page.rb
@@ -125,7 +125,7 @@ def publish
:published_id => published_page.id
)
- expire_varnish if Rails.env.production?
+ UbiquoDesign.cache_manager.expire_page(self) if Rails.env.production?
end
return true
rescue Exception => e
@@ -157,17 +157,6 @@ def expire_varnish
true
end
- def varnish_request(url)
- Rails.logger.warn "PURGING #{url}"
- puts "PURGING #{url}"
- begin
- http = Net::HTTP.new(VARNISH_SERVER)
- http.send_request('BAN', url)
- rescue
- ''
- end
- end
-
# Returns true if the page has been published
def published?
published_id
diff --git a/ubiquo_design/lib/ubiquo_design/cache_managers/base.rb b/ubiquo_design/lib/ubiquo_design/cache_managers/base.rb
index 134e2760..94be1616 100644
--- a/ubiquo_design/lib/ubiquo_design/cache_managers/base.rb
+++ b/ubiquo_design/lib/ubiquo_design/cache_managers/base.rb
@@ -286,21 +286,6 @@ def with_instance_content(widget, options)
if options[:current_model].present? && options[:current_model].to_s != key.to_s
next
end
- if val[:identifier].is_a?(Hash)
- if options[:scope].respond_to?(:params)
- true_identifier = val[:identifier].keys.first
- else
- true_identifier = val[:identifier].values.first
- end
- elsif val[:identifier].is_a?(Array)
- if options[:scope].respond_to?(:params)
- true_identifier = val[:identifier].first
- else
- true_identifier = val[:identifier].last
- end
- else
- true_identifier = val[:identifier]
- end
p_i = key.to_s + '_'
p_i += process_params(val, options)
diff --git a/ubiquo_design/lib/ubiquo_design/cache_managers/varnish.rb b/ubiquo_design/lib/ubiquo_design/cache_managers/varnish.rb
new file mode 100644
index 00000000..4bf71fc6
--- /dev/null
+++ b/ubiquo_design/lib/ubiquo_design/cache_managers/varnish.rb
@@ -0,0 +1,102 @@
+module UbiquoDesign
+ module CacheManagers
+ # Varnish implementation for the cache manager
+ class Varnish < UbiquoDesign::CacheManagers::Base
+
+# CONFIG = Ubiquo::Config.context(:ubiquo_design).get(:varnish)
+
+ class << self
+
+ # This method is called when rendering +page+ and returns a hash where
+ # the keys are the ids of the page widgets that are esi widgets,
+ # and the value is an esi:include tag
+ def multi_get(page, options = {})
+ {}.tap do |widgets_by_id|
+ request = options[:scope].request
+ page.blocks.each do |block|
+ block.real_block.widgets.each do |widget|
+ if esi_widget?(widget)
+ new_params = request.query_parameters.merge('widget' => widget.id)
+ esi_url = request.url.gsub("?#{request.query_string}", '') + "?#{new_params.to_query}"
+ widgets_by_id[widget.id] = ""
+ end
+ end
+ end
+ end
+ end
+
+ # Caches the content of a widget
+ # Simply return, since the real caching is done by Varnish when the request is finished
+ def cache(widget_id, contents, options = {}); end
+
+ # Returns true if the widget is an esi widget
+ def esi_widget?(widget)
+ # TODO
+ defined? ESI_ENABLED
+ end
+
+ # Expires the applicable content of a widget given its id
+ # This means all the urls where the widget is cached
+ # +widget+ is a Widget instance
+ def expire(widget)
+ Rails.logger.debug "-- Expiring Varnish --"
+
+ # We ban all the urls of the related page that also contain the widget id
+ # e.g. /url/of/page?param=4&widget=42
+ ban_url = Regexp.escape(widget.page.url + "?") + ".*widget=#{widget.id}"
+
+ # And we also ban all the urls that do not contain the widget param
+ # (i.e. the "full page", which can have different representations if
+ # it has different params).
+ # This is needed since else the esi fragment would be new,
+ # but the page would still be cached.
+ # The other cached pages with the "widget" param are in fact
+ # other widgets of this page, which have not been modified
+ # e.g. /url/of/page?param=4 (this will be expired because !~)
+ ban_negative_url = Regexp.escape(widget.page.url + '?') + ".*widget="
+
+ # Now do the real job. This is the correct order to avoid recaching old data
+ ban(ban_url)
+ ban_negative(ban_negative_url)
+ end
+
+ # Expires a +page+, with all its possibles urls and params
+ def expire_page(page)
+ # We cannot simply ban url_page* since url_page could be a segment of
+ # another page, so:
+ # ban the url_page with params
+ ban(Regexp.escape(page.url + "?"))
+ # ban the exact page url, with or without trailing slash
+ ban(Regexp.escape(page.url) + "[\/]?$")
+ end
+
+ protected
+
+ # Bans all urls that match +url+ (which is interpreted as a regexp)
+ def ban(url)
+ varnish_request('BAN', url)
+ end
+
+ # Bans all urls not matching +url+
+ def ban_negative(url)
+ varnish_request('BAN_NEG', url)
+ end
+
+ # removes the widget content from the store
+ def varnish_request method, url
+ Rails.logger.debug "Varnish #{method} request for url #{url}"
+ # TODO deal with multiple servers
+ begin
+ http = Net::HTTP.new(VARNISH_SERVER, VARNISH_PORT)
+ http.set_debug_output($stderr) # TODO temporal
+ http.send_request(method, url)
+ rescue
+ Rails.logger.warn "Cache is not available, impossible to delete cache: "+ $!.inspect
+ end
+ end
+
+ end
+
+ end
+ end
+end
diff --git a/ubiquo_design/lib/ubiquo_design/render_page.rb b/ubiquo_design/lib/ubiquo_design/render_page.rb
index 6d77c34e..3c5e6344 100644
--- a/ubiquo_design/lib/ubiquo_design/render_page.rb
+++ b/ubiquo_design/lib/ubiquo_design/render_page.rb
@@ -22,21 +22,12 @@ def render_page(page)
def render_block(block, cached_widgets = {})
uhook_collect_widgets(block) do |widget|
next unless widget.valid?
- if esi_widget?(widget)
- new_params = request.query_parameters.merge('widget' => widget.id)
- ""
- else
- (cached_widgets[widget.id] || render_widget(widget)).tap do |output|
- # A widget didn't return an string, return inmediately
- return unless output
- end
+ (cached_widgets[widget.id] || render_widget(widget)).tap do |output|
+ # A widget didn't return an string, return inmediately
+ return unless output
end
end
end
-
- def esi_widget?(widget)
- Rails.env.production?
- end
def template_directory
Rails.env.test? ? File.join(ActiveSupport::TestCase.fixture_path, "templates") :