From fa0ba677538588086d83c97c0ea56f9cd1556590 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Tue, 30 Jan 2024 19:21:30 +0100
Subject: [PATCH] Change materialized views to be refreshed concurrently to
 avoid locks (#29015)

---
 app/models/account_summary.rb                               | 2 ++
 app/models/follow_recommendation.rb                         | 2 ++
 db/migrate/20210322164601_create_account_summaries.rb       | 2 +-
 ...0505174616_update_follow_recommendations_to_version_2.rb | 2 +-
 .../20211213040746_update_account_summaries_to_version_2.rb | 6 +++---
 .../20230818141056_create_global_follow_recommendations.rb  | 2 +-
 .../20230818142253_drop_follow_recommendations.rb           | 2 +-
 7 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/app/models/account_summary.rb b/app/models/account_summary.rb
index f05281636..30ada50cc 100644
--- a/app/models/account_summary.rb
+++ b/app/models/account_summary.rb
@@ -19,6 +19,8 @@ class AccountSummary < ApplicationRecord
   scope :filtered, -> { where.missing(:follow_recommendation_suppressions) }
 
   def self.refresh
+    Scenic.database.refresh_materialized_view(table_name, concurrently: true, cascade: false)
+  rescue ActiveRecord::StatementInvalid
     Scenic.database.refresh_materialized_view(table_name, concurrently: false, cascade: false)
   end
 
diff --git a/app/models/follow_recommendation.rb b/app/models/follow_recommendation.rb
index 9d2648394..6b49a3ca6 100644
--- a/app/models/follow_recommendation.rb
+++ b/app/models/follow_recommendation.rb
@@ -19,6 +19,8 @@ class FollowRecommendation < ApplicationRecord
   scope :localized, ->(locale) { joins(:account_summary).merge(AccountSummary.localized(locale)) }
 
   def self.refresh
+    Scenic.database.refresh_materialized_view(table_name, concurrently: true, cascade: false)
+  rescue ActiveRecord::StatementInvalid
     Scenic.database.refresh_materialized_view(table_name, concurrently: false, cascade: false)
   end
 
diff --git a/db/migrate/20210322164601_create_account_summaries.rb b/db/migrate/20210322164601_create_account_summaries.rb
index 8d18e9eeb..5c93291e0 100644
--- a/db/migrate/20210322164601_create_account_summaries.rb
+++ b/db/migrate/20210322164601_create_account_summaries.rb
@@ -2,7 +2,7 @@
 
 class CreateAccountSummaries < ActiveRecord::Migration[5.2]
   def change
-    create_view :account_summaries, materialized: { no_data: true }
+    create_view :account_summaries, materialized: true
 
     # To be able to refresh the view concurrently,
     # at least one unique index is required
diff --git a/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb b/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb
index 22c27a0e7..3a9024ffc 100644
--- a/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb
+++ b/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb
@@ -6,7 +6,7 @@ class UpdateFollowRecommendationsToVersion2 < ActiveRecord::Migration[6.1]
 
   def up
     drop_view :follow_recommendations
-    create_view :follow_recommendations, version: 2, materialized: { no_data: true }
+    create_view :follow_recommendations, version: 2, materialized: true
 
     # To be able to refresh the view concurrently,
     # at least one unique index is required
diff --git a/db/migrate/20211213040746_update_account_summaries_to_version_2.rb b/db/migrate/20211213040746_update_account_summaries_to_version_2.rb
index e347a874f..a82cf4afa 100644
--- a/db/migrate/20211213040746_update_account_summaries_to_version_2.rb
+++ b/db/migrate/20211213040746_update_account_summaries_to_version_2.rb
@@ -4,7 +4,7 @@ class UpdateAccountSummariesToVersion2 < ActiveRecord::Migration[6.1]
   def up
     reapplication_follow_recommendations_v2 do
       drop_view :account_summaries, materialized: true
-      create_view :account_summaries, version: 2, materialized: { no_data: true }
+      create_view :account_summaries, version: 2, materialized: true
       safety_assured { add_index :account_summaries, :account_id, unique: true }
     end
   end
@@ -12,7 +12,7 @@ class UpdateAccountSummariesToVersion2 < ActiveRecord::Migration[6.1]
   def down
     reapplication_follow_recommendations_v2 do
       drop_view :account_summaries, materialized: true
-      create_view :account_summaries, version: 1, materialized: { no_data: true }
+      create_view :account_summaries, version: 1, materialized: true
       safety_assured { add_index :account_summaries, :account_id, unique: true }
     end
   end
@@ -20,7 +20,7 @@ class UpdateAccountSummariesToVersion2 < ActiveRecord::Migration[6.1]
   def reapplication_follow_recommendations_v2
     drop_view :follow_recommendations, materialized: true
     yield
-    create_view :follow_recommendations, version: 2, materialized: { no_data: true }
+    create_view :follow_recommendations, version: 2, materialized: true
     safety_assured { add_index :follow_recommendations, :account_id, unique: true }
   end
 end
diff --git a/db/migrate/20230818141056_create_global_follow_recommendations.rb b/db/migrate/20230818141056_create_global_follow_recommendations.rb
index b88c71b9d..1a3f23d22 100644
--- a/db/migrate/20230818141056_create_global_follow_recommendations.rb
+++ b/db/migrate/20230818141056_create_global_follow_recommendations.rb
@@ -2,7 +2,7 @@
 
 class CreateGlobalFollowRecommendations < ActiveRecord::Migration[7.0]
   def change
-    create_view :global_follow_recommendations, materialized: { no_data: true }
+    create_view :global_follow_recommendations, materialized: true
     safety_assured { add_index :global_follow_recommendations, :account_id, unique: true }
   end
 end
diff --git a/db/post_migrate/20230818142253_drop_follow_recommendations.rb b/db/post_migrate/20230818142253_drop_follow_recommendations.rb
index 95913d6ca..e0a24753c 100644
--- a/db/post_migrate/20230818142253_drop_follow_recommendations.rb
+++ b/db/post_migrate/20230818142253_drop_follow_recommendations.rb
@@ -6,7 +6,7 @@ class DropFollowRecommendations < ActiveRecord::Migration[7.0]
   end
 
   def down
-    create_view :follow_recommendations, version: 2, materialized: { no_data: true }
+    create_view :follow_recommendations, version: 2, materialized: true
     safety_assured { add_index :follow_recommendations, :account_id, unique: true }
   end
 end