mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
stop spawning off for advert updates
This commit is contained in:
parent
dd7aca809a
commit
cc4103fcea
5 changed files with 100 additions and 28 deletions
|
@ -19,7 +19,6 @@ defmodule Philomena.Adverts do
|
|||
|> order_by(asc: fragment("random()"))
|
||||
|> limit(1)
|
||||
|> Repo.one()
|
||||
|> record_impression()
|
||||
end
|
||||
|
||||
def random_live_for(image) do
|
||||
|
@ -33,25 +32,6 @@ defmodule Philomena.Adverts do
|
|||
|> order_by(asc: fragment("random()"))
|
||||
|> limit(1)
|
||||
|> Repo.one()
|
||||
|> record_impression()
|
||||
end
|
||||
|
||||
def click(%Advert{} = advert) do
|
||||
spawn(fn ->
|
||||
query = where(Advert, id: ^advert.id)
|
||||
Repo.update_all(query, inc: [clicks: 1])
|
||||
end)
|
||||
end
|
||||
|
||||
defp record_impression(nil), do: nil
|
||||
|
||||
defp record_impression(advert) do
|
||||
spawn(fn ->
|
||||
query = where(Advert, id: ^advert.id)
|
||||
Repo.update_all(query, inc: [impressions: 1])
|
||||
end)
|
||||
|
||||
advert
|
||||
end
|
||||
|
||||
defp sfw?(image) do
|
||||
|
|
|
@ -17,6 +17,9 @@ defmodule Philomena.Application do
|
|||
# Start the Ecto repository
|
||||
Philomena.Repo,
|
||||
|
||||
# Background queueing system
|
||||
Philomena.ExqSupervisor,
|
||||
|
||||
# Starts a worker by calling: Philomena.Worker.start_link(arg)
|
||||
# {Philomena.Worker, arg},
|
||||
Philomena.Servers.ImageProcessor,
|
||||
|
@ -28,6 +31,7 @@ defmodule Philomena.Application do
|
|||
{Phoenix.PubSub, [name: Philomena.PubSub, adapter: Phoenix.PubSub.PG2]},
|
||||
|
||||
# Start the endpoint when the application starts
|
||||
PhilomenaWeb.AdvertUpdater,
|
||||
PhilomenaWeb.StatsUpdater,
|
||||
PhilomenaWeb.UserFingerprintUpdater,
|
||||
PhilomenaWeb.UserIpUpdater,
|
||||
|
|
81
lib/philomena_web/advert_updater.ex
Normal file
81
lib/philomena_web/advert_updater.ex
Normal file
|
@ -0,0 +1,81 @@
|
|||
defmodule PhilomenaWeb.AdvertUpdater do
|
||||
alias Philomena.Adverts.Advert
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
def child_spec([]) do
|
||||
%{
|
||||
id: PhilomenaWeb.AdvertUpdater,
|
||||
start: {PhilomenaWeb.AdvertUpdater, :start_link, [[]]}
|
||||
}
|
||||
end
|
||||
|
||||
def start_link([]) do
|
||||
{:ok, spawn_link(&init/0)}
|
||||
end
|
||||
|
||||
def cast(type, advert_id) when type in [:impression, :click] do
|
||||
pid = Process.whereis(:advert_updater)
|
||||
if pid, do: send(pid, {type, advert_id})
|
||||
end
|
||||
|
||||
defp init do
|
||||
Process.register(self(), :advert_updater)
|
||||
run()
|
||||
end
|
||||
|
||||
defp run do
|
||||
# Read impression counts from mailbox
|
||||
{impressions, clicks} = receive_all()
|
||||
|
||||
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
||||
|
||||
# Create insert statements for Ecto
|
||||
impressions = Enum.map(impressions, &impressions_insert_all(&1, now))
|
||||
clicks = Enum.map(clicks, &clicks_insert_all(&1, now))
|
||||
|
||||
# Merge into table
|
||||
impressions_update = update(Advert, inc: [impressions: fragment("EXCLUDED.impressions")])
|
||||
clicks_update = update(Advert, inc: [clicks: fragment("EXCLUDED.clicks")])
|
||||
|
||||
Repo.insert_all(Advert, impressions, on_conflict: impressions_update, conflict_target: [:id])
|
||||
Repo.insert_all(Advert, clicks, on_conflict: clicks_update, conflict_target: [:id])
|
||||
|
||||
:timer.sleep(:timer.seconds(10))
|
||||
|
||||
run()
|
||||
end
|
||||
|
||||
defp receive_all(impressions \\ %{}, clicks \\ %{}) do
|
||||
receive do
|
||||
{:impression, advert_id} ->
|
||||
impressions = Map.update(impressions, advert_id, 1, &(&1 + 1))
|
||||
receive_all(impressions, clicks)
|
||||
|
||||
{:click, advert_id} ->
|
||||
clicks = Map.update(clicks, advert_id, 1, &(&1 + 1))
|
||||
receive_all(impressions, clicks)
|
||||
after
|
||||
0 ->
|
||||
{impressions, clicks}
|
||||
end
|
||||
end
|
||||
|
||||
defp impressions_insert_all({advert_id, impressions}, now) do
|
||||
%{
|
||||
id: advert_id,
|
||||
impressions: impressions,
|
||||
created_at: now,
|
||||
updated_at: now
|
||||
}
|
||||
end
|
||||
|
||||
defp clicks_insert_all({advert_id, clicks}, now) do
|
||||
%{
|
||||
id: advert_id,
|
||||
clicks: clicks,
|
||||
created_at: now,
|
||||
updated_at: now
|
||||
}
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.AdvertController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Adverts
|
||||
alias PhilomenaWeb.AdvertUpdater
|
||||
alias Philomena.Adverts.Advert
|
||||
|
||||
plug :load_resource, model: Advert
|
||||
|
@ -9,9 +9,8 @@ defmodule PhilomenaWeb.AdvertController do
|
|||
def show(conn, _params) do
|
||||
advert = conn.assigns.advert
|
||||
|
||||
Adverts.click(advert)
|
||||
AdvertUpdater.cast(:click, advert.id)
|
||||
|
||||
conn
|
||||
|> redirect(external: advert.link)
|
||||
redirect(conn, external: advert.link)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
defmodule PhilomenaWeb.AdvertPlug do
|
||||
alias PhilomenaWeb.AdvertUpdater
|
||||
alias Philomena.Adverts
|
||||
alias Plug.Conn
|
||||
|
||||
|
@ -9,15 +10,14 @@ defmodule PhilomenaWeb.AdvertPlug do
|
|||
image = conn.assigns[:image]
|
||||
show_ads? = show_ads?(user)
|
||||
|
||||
conn
|
||||
|> maybe_assign_ad(image, show_ads?)
|
||||
maybe_assign_ad(conn, image, show_ads?)
|
||||
end
|
||||
|
||||
defp maybe_assign_ad(conn, nil, true),
|
||||
do: Conn.assign(conn, :advert, Adverts.random_live())
|
||||
do: Conn.assign(conn, :advert, record_impression(Adverts.random_live()))
|
||||
|
||||
defp maybe_assign_ad(conn, image, true),
|
||||
do: Conn.assign(conn, :advert, Adverts.random_live_for(image))
|
||||
do: Conn.assign(conn, :advert, record_impression(Adverts.random_live_for(image)))
|
||||
|
||||
defp maybe_assign_ad(conn, _image, _false),
|
||||
do: conn
|
||||
|
@ -27,4 +27,12 @@ defmodule PhilomenaWeb.AdvertPlug do
|
|||
|
||||
defp show_ads?(_user),
|
||||
do: true
|
||||
|
||||
defp record_impression(nil), do: nil
|
||||
|
||||
defp record_impression(advert) do
|
||||
AdvertUpdater.cast(:impression, advert.id)
|
||||
|
||||
advert
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue