From 11e42d660124bca4a5422079f41d808081ed079b Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 1 Dec 2023 10:38:36 +0100 Subject: [PATCH] feat(background): add a job to refresh participant stats Signed-off-by: Thomas Citharel --- config/config.exs | 1 + .../workers/refresh_participant_stats.ex | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 lib/service/workers/refresh_participant_stats.ex diff --git a/config/config.exs b/config/config.exs index f590043e3..d75b2e10a 100644 --- a/config/config.exs +++ b/config/config.exs @@ -324,6 +324,7 @@ config :mobilizon, Oban, {"@hourly", Mobilizon.Service.Workers.ExportCleanerWorker, queue: :background}, {"@hourly", Mobilizon.Service.Workers.SendActivityRecapWorker, queue: :notifications}, {"@daily", Mobilizon.Service.Workers.CleanOldActivityWorker, queue: :background}, + {"@daily", Mobilizon.Service.Workers.RefreshParticipantStats, queue: :background}, {"@hourly", Mobilizon.Service.Workers.CleanApplicationData, queue: :background, args: %{type: :application_token}}, {"@hourly", Mobilizon.Service.Workers.CleanApplicationData, diff --git a/lib/service/workers/refresh_participant_stats.ex b/lib/service/workers/refresh_participant_stats.ex new file mode 100644 index 000000000..b41cea26e --- /dev/null +++ b/lib/service/workers/refresh_participant_stats.ex @@ -0,0 +1,61 @@ +defmodule Mobilizon.Service.Workers.RefreshParticipantStats do + @moduledoc """ + Worker to refresh the participant event stats based on participants data + """ + + use Oban.Worker, unique: [period: :infinity, keys: [:event_uuid, :action]] + + alias Mobilizon.Events + alias Mobilizon.Events.{Event, Participant} + alias Mobilizon.Storage.Page + alias Oban.Job + require Logger + + @impl Oban.Worker + @spec perform(Oban.Job.t()) :: :ok + def perform(%Job{}) do + refresh_participant_stats() + end + + def refresh_participant_stats do + Logger.info("Launching RefreshParticipantStats job") + %Page{elements: future_events} = Events.list_events(1, 100_000_000) + + updated_events_count = + Enum.reduce(future_events, 0, fn %Event{} = event, updated_events_count -> + participants = Events.list_all_participants_for_event(event.id) + + participant_stats = + Enum.reduce( + participants, + %{ + not_approved: 0, + not_confirmed: 0, + rejected: 0, + participant: 0, + moderator: 0, + administrator: 0, + creator: 0 + }, + fn %Participant{role: role}, acc -> + Map.update(acc, role, 1, &(&1 + 1)) + end + ) + + if participant_stats != Map.from_struct(event.participant_stats) do + Logger.debug("Uupdating event #{event.id} because of wrong participant_stats") + + Events.update_event(event, %{ + participant_stats: participant_stats + }) + + updated_events_count + 1 + else + Logger.debug("Skipped updating event #{event.id}") + updated_events_count + end + end) + + Logger.info("Updated #{updated_events_count} events on #{length(future_events)}") + end +end