Skip to content

Commit

Permalink
core: on insert of duplicate task, handle error more gracefully (0.x) (
Browse files Browse the repository at this point in the history
  • Loading branch information
mworrell committed Mar 19, 2023
1 parent 8c98467 commit 16dfdb2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 30 deletions.
11 changes: 8 additions & 3 deletions src/db/z_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,15 @@ insert(Table, Props, Context) ->
F = fun(C) ->
DbDriver = z_context:db_driver(Context),
case equery1(DbDriver, C, FinalSql, Parameters) of
{ok, Id} -> {ok, Id};
{error, noresult} -> {ok, undefined};
{ok, Id} ->
{ok, Id};
{error, noresult} ->
{ok, undefined};
{error, #error{ codename = unique_violation } = Reason} = Error ->
lager:notice("z_db error ~p in insert into ~p with ~p", [Reason, Table, Parameters]),
Error;
{error, Reason} = Error ->
lager:error("z_db error ~p in query ~s with ~p", [Reason, FinalSql, Parameters]),
lager:error("z_db error ~p in insert into ~p with ~p", [Reason, Table, Parameters]),
Error
end
end,
Expand Down
70 changes: 43 additions & 27 deletions src/support/z_pivot_rsc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
]).

-include("zotonic.hrl").
-include_lib("epgsql/include/epgsql.hrl").

% Interval (in seconds) to check if there are any items to be pivoted.
-define(PIVOT_POLL_INTERVAL_FAST, 2).
Expand Down Expand Up @@ -176,33 +177,48 @@ insert_task(Module, Function, UniqueKey, Args, Context) ->

%% @doc Insert a slow running pivot task with unique key and arguments that should start after Seconds seconds.
insert_task_after(SecondsOrDate, Module, Function, UniqueKey, Args, Context) ->
z_db:transaction(fun(Ctx) -> insert_transaction(SecondsOrDate, Module, Function, UniqueKey, Args, Ctx) end, Context).

insert_transaction(SecondsOrDate, Module, Function, UniqueKey, Args, Context) ->
Due = to_utc_date(SecondsOrDate),
UniqueKeyBin = z_convert:to_binary(UniqueKey),
Fields = [
{module, Module},
{function, Function},
{key, UniqueKeyBin},
{args, Args},
{due, Due}
],
case z_db:q1("select id
from pivot_task_queue
where module = $1 and function = $2 and key = $3",
[Module, Function, UniqueKeyBin],
Context)
of
undefined ->
z_db:insert(pivot_task_queue, Fields, Context);
Id when is_integer(Id) ->
case Due of
undefined -> nop;
_ -> z_db:update(pivot_task_queue, Id, Fields, Context)
end,
{ok, Id}
end.
UniqueKeyBin = z_convert:to_binary(UniqueKey),
Result = z_db:transaction(fun(Ctx) -> insert_transaction(SecondsOrDate, Module, Function, UniqueKeyBin, Args, Ctx) end, Context),
case Result of
{ok, _} = Ok ->
Ok;
{error, #error{ codename = unique_violation }} ->
Id = z_db:q1("
select id
from pivot_task_queue
where module = $1 and function = $2 and key = $3",
[Module, Function, UniqueKeyBin],
Context),
{ok, Id};
{error, _} = Error ->
Error
end.

insert_transaction(SecondsOrDate, Module, Function, UniqueKeyBin, Args, Context) ->
Due = to_utc_date(SecondsOrDate),
Fields = [
{module, Module},
{function, Function},
{key, UniqueKeyBin},
{args, Args},
{due, Due}
],
case z_db:q1("select id
from pivot_task_queue
where module = $1 and function = $2 and key = $3
for update",
[Module, Function, UniqueKeyBin],
Context)
of
undefined ->
z_db:insert(pivot_task_queue, Fields, Context);
Id when is_integer(Id) ->
case Due of
undefined -> nop;
_ -> z_db:update(pivot_task_queue, Id, Fields, Context)
end,
{ok, Id}
end.


get_task(Context) ->
Expand Down

0 comments on commit 16dfdb2

Please sign in to comment.