From c202afdec67f3ed017ddb343206e2874fe911913 Mon Sep 17 00:00:00 2001 From: PJ Date: Wed, 9 Aug 2023 19:07:57 +0100 Subject: [PATCH] Show billboards to users by location (async requests) (#19886) * use HTTP_CLIENT_GEO in billboards show action * limit targeting to signed in users * re-add cypress test * simplify billboards request spec * fix header problems hopefully? * whoops * Squash filleduchaos/caching-billboards-by-location * export ISO 3166-2 regions * wip * remove ISO 3166-2 regions * finally, a VCL config that...works? * update billboard controller & specs * fix specs * clean up and document VCL some more * remove vcl_init sub * remove billboard fragment caching --- app/controllers/billboards_controller.rb | 16 +++- app/controllers/concerns/caching_headers.rb | 5 + app/models/display_ad.rb | 3 +- app/views/billboards/show.html.erb | 8 +- app/views/layouts/_footer.html.erb | 10 +- config/fastly/snippets/client_geolocation.vcl | 30 +++++- .../homeFeedFlows/billboards.spec.js | 60 ++++++++++++ spec/requests/billboards_spec.rb | 94 +++++++++++++++++-- spec/support/seeds/seeds_e2e.rb | 22 ++++- 9 files changed, 225 insertions(+), 23 deletions(-) create mode 100644 cypress/e2e/seededFlows/homeFeedFlows/billboards.spec.js diff --git a/app/controllers/billboards_controller.rb b/app/controllers/billboards_controller.rb index 6281ea420..60fca1073 100644 --- a/app/controllers/billboards_controller.rb +++ b/app/controllers/billboards_controller.rb @@ -5,7 +5,12 @@ class BillboardsController < ApplicationController def show skip_authorization - set_cache_control_headers(CACHE_EXPIRY_FOR_BILLBOARDS) unless session_current_user_id + unless session_current_user_id + set_cache_control_headers(CACHE_EXPIRY_FOR_BILLBOARDS) + if FeatureFlag.enabled?(Geolocation::FEATURE_FLAG) + add_vary_header("X-Cacheable-Client-Geo") + end + end if placement_area if params[:username].present? && params[:slug].present? @@ -18,6 +23,7 @@ class BillboardsController < ApplicationController user_id: current_user&.id, article: @article ? ArticleDecorator.new(@article) : nil, user_tags: user_tags, + location: client_geolocation, ) if @billboard && !session_current_user_id @@ -39,4 +45,12 @@ class BillboardsController < ApplicationController current_user&.cached_followed_tag_names end + + def client_geolocation + if session_current_user_id + request.headers["X-Client-Geo"] + else + request.headers["X-Cacheable-Client-Geo"] + end + end end diff --git a/app/controllers/concerns/caching_headers.rb b/app/controllers/concerns/caching_headers.rb index cd2e1f081..8159871c2 100644 --- a/app/controllers/concerns/caching_headers.rb +++ b/app/controllers/concerns/caching_headers.rb @@ -44,6 +44,11 @@ module CachingHeaders response.headers["Surrogate-Key"] = surrogate_keys.join(" ") end + def add_vary_header(*vary_keys) + existing = response.headers["Vary"] + response.headers["Vary"] = [existing, *vary_keys].compact.join(", ") + end + private def build_surrogate_control(max_age, stale_while_revalidate: nil, stale_if_error: 26_400) diff --git a/app/models/display_ad.rb b/app/models/display_ad.rb index dc1e28381..2809c07d3 100644 --- a/app/models/display_ad.rb +++ b/app/models/display_ad.rb @@ -60,7 +60,7 @@ class DisplayAd < ApplicationRecord scope :seldom_seen, ->(area) { where("impressions_count < ?", low_impression_count(area)).or(where(priority: true)) } - def self.for_display(area:, user_signed_in:, user_id: nil, article: nil, user_tags: nil) + def self.for_display(area:, user_signed_in:, user_id: nil, article: nil, user_tags: nil, location: nil) permit_adjacent = article ? article.permit_adjacent_sponsors? : true billboards_for_display = Billboards::FilteredAdsQuery.call( @@ -73,6 +73,7 @@ class DisplayAd < ApplicationRecord permit_adjacent_sponsors: permit_adjacent, user_id: user_id, user_tags: user_tags, + location: location, ) case rand(99) # output integer from 0-99 diff --git a/app/views/billboards/show.html.erb b/app/views/billboards/show.html.erb index b2f3e221a..a54cca829 100644 --- a/app/views/billboards/show.html.erb +++ b/app/views/billboards/show.html.erb @@ -1,9 +1,3 @@ <% if @billboard %> - <% if user_signed_in? %> - <%= render partial: "shared/billboard", locals: { billboard: @billboard, data_context_type: BillboardEvent::CONTEXT_TYPE_ARTICLE } %> - <% else %> - <% cache([params[:username], params[:slug], params[:placement_area]], expires_in: 15.minutes) do %> - <%= render partial: "shared/billboard", locals: { billboard: @billboard, data_context_type: BillboardEvent::CONTEXT_TYPE_ARTICLE } %> - <% end %> - <% end %> + <%= render partial: "shared/billboard", locals: { billboard: @billboard, data_context_type: BillboardEvent::CONTEXT_TYPE_ARTICLE } %> <% end %> diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index fb5a8879e..55818aa17 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -1,9 +1,9 @@ <% navigation_links = Rails.cache.fetch("navigation_links", expires_in: 15.minutes) do - { - default_nav_ids: NavigationLink.default_section.ordered.ids, - other_nav_ids: NavigationLink.other_section.ordered.ids - } -end %> + { + default_nav_ids: NavigationLink.default_section.ordered.ids, + other_nav_ids: NavigationLink.other_section.ordered.ids + } + end %>