From 87214b038fbcc163394e90f2eeb7ca670edb03d2 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Wed, 4 May 2022 08:21:15 +0200
Subject: [PATCH] Add appropriate timeouts for Repo.transactions

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 lib/service/actor_suspension.ex               |  2 +-
 lib/service/site_map.ex                       | 57 ++++++++++---------
 .../workers/send_activity_recap_worker.ex     | 45 ++++++++-------
 lib/web/email/event.ex                        | 21 ++++---
 4 files changed, 67 insertions(+), 58 deletions(-)

diff --git a/lib/service/actor_suspension.ex b/lib/service/actor_suspension.ex
index 96977ead0..466b4bbba 100644
--- a/lib/service/actor_suspension.ex
+++ b/lib/service/actor_suspension.ex
@@ -64,7 +64,7 @@ defmodule Mobilizon.Service.ActorSuspension do
 
     Logger.debug("Going to run the transaction")
 
-    case Repo.transaction(multi) do
+    case Repo.transaction(multi, timeout: 60_000) do
       {:ok, %{actor: %Actor{} = actor}} ->
         {:ok, true} = Cachex.del(:activity_pub, "actor_#{actor.preferred_username}")
         Cachable.clear_all_caches(actor)
diff --git a/lib/service/site_map.ex b/lib/service/site_map.ex
index ff905f135..389b9f4a9 100644
--- a/lib/service/site_map.ex
+++ b/lib/service/site_map.ex
@@ -29,35 +29,38 @@ defmodule Mobilizon.Service.SiteMap do
       gzip: false
     ]
 
-    Repo.transaction(fn ->
-      Events.stream_events_for_sitemap()
-      |> Stream.concat(Actors.list_groups_for_stream())
-      |> Stream.concat(Posts.list_posts_for_stream())
-      |> Stream.concat(
-        Enum.map(static_routes, fn route ->
-          {url, frequency} =
-            case route do
-              {url, frequency} -> {url, frequency}
-              url when is_binary(url) -> {url, @default_static_frequency}
-            end
+    Repo.transaction(
+      fn ->
+        Events.stream_events_for_sitemap()
+        |> Stream.concat(Actors.list_groups_for_stream())
+        |> Stream.concat(Posts.list_posts_for_stream())
+        |> Stream.concat(
+          Enum.map(static_routes, fn route ->
+            {url, frequency} =
+              case route do
+                {url, frequency} -> {url, frequency}
+                url when is_binary(url) -> {url, @default_static_frequency}
+              end
 
-          %{url: url, updated_at: nil, frequence: frequency}
+            %{url: url, updated_at: nil, frequence: frequency}
+          end)
+        )
+        |> Stream.map(fn %{url: url, updated_at: updated_at} = args ->
+          frequence = Map.get(args, :frequence, :weekly)
+
+          %Sitemapper.URL{
+            loc: url,
+            changefreq: frequence,
+            lastmod: check_date_time(updated_at)
+          }
         end)
-      )
-      |> Stream.map(fn %{url: url, updated_at: updated_at} = args ->
-        frequence = Map.get(args, :frequence, :weekly)
-
-        %Sitemapper.URL{
-          loc: url,
-          changefreq: frequence,
-          lastmod: check_date_time(updated_at)
-        }
-      end)
-      |> Sitemapper.generate(config)
-      |> Sitemapper.persist(config)
-      |> Sitemapper.ping(config)
-      |> Stream.run()
-    end)
+        |> Sitemapper.generate(config)
+        |> Sitemapper.persist(config)
+        |> Sitemapper.ping(config)
+        |> Stream.run()
+      end,
+      timeout: :infinity
+    )
   end
 
   # Sometimes we use naive datetimes
diff --git a/lib/service/workers/send_activity_recap_worker.ex b/lib/service/workers/send_activity_recap_worker.ex
index 6d0d163f4..ec8a7b824 100644
--- a/lib/service/workers/send_activity_recap_worker.ex
+++ b/lib/service/workers/send_activity_recap_worker.ex
@@ -20,27 +20,30 @@ defmodule Mobilizon.Service.Workers.SendActivityRecapWorker do
 
   @impl Oban.Worker
   def perform(%Job{}) do
-    Repo.transaction(fn ->
-      Users.stream_users_for_recap()
-      |> Enum.to_list()
-      |> Repo.preload([:settings, :activity_settings])
-      |> Enum.filter(&filter_elegible_users/1)
-      |> Enum.map(fn %User{} = user ->
-        %{
-          activities: activities_for_user(user),
-          user: user
-        }
-      end)
-      |> Enum.filter(fn %{activities: activities, user: _user} -> length(activities) > 0 end)
-      |> Enum.map(fn %{
-                       activities: activities,
-                       user:
-                         %User{settings: %Setting{group_notifications: group_notifications}} =
-                           user
-                     } ->
-        Email.send(user, activities, recap: group_notifications)
-      end)
-    end)
+    Repo.transaction(
+      fn ->
+        Users.stream_users_for_recap()
+        |> Enum.to_list()
+        |> Repo.preload([:settings, :activity_settings])
+        |> Enum.filter(&filter_elegible_users/1)
+        |> Enum.map(fn %User{} = user ->
+          %{
+            activities: activities_for_user(user),
+            user: user
+          }
+        end)
+        |> Enum.filter(fn %{activities: activities, user: _user} -> length(activities) > 0 end)
+        |> Enum.map(fn %{
+                         activities: activities,
+                         user:
+                           %User{settings: %Setting{group_notifications: group_notifications}} =
+                             user
+                       } ->
+          Email.send(user, activities, recap: group_notifications)
+        end)
+      end,
+      timeout: :infinity
+    )
   end
 
   defp activities_for_user(
diff --git a/lib/web/email/event.ex b/lib/web/email/event.ex
index 6b24a0d2b..7b10f83d0 100644
--- a/lib/web/email/event.ex
+++ b/lib/web/email/event.ex
@@ -82,15 +82,18 @@ defmodule Mobilizon.Web.Email.Event do
       |> MapSet.new()
 
     if MapSet.size(diff) > 0 do
-      Repo.transaction(fn ->
-        event_id
-        |> Events.list_local_emails_user_participants_for_event_query()
-        |> Repo.stream()
-        |> Enum.to_list()
-        |> Enum.each(
-          &send_notification_for_event_update_to_participant(&1, old_event, event, diff)
-        )
-      end)
+      Repo.transaction(
+        fn ->
+          event_id
+          |> Events.list_local_emails_user_participants_for_event_query()
+          |> Repo.stream()
+          |> Enum.to_list()
+          |> Enum.each(
+            &send_notification_for_event_update_to_participant(&1, old_event, event, diff)
+          )
+        end,
+        timeout: 120_000
+      )
     else
       {:ok, :ok}
     end