commanded/commanded-ecto-projections

Don't call the `after_update/3` function when idempotency check fails

slashdotdash opened this issue · 2 comments

Commanded Ecto projections uses the projection_versions table to ensure that an event cannot be projected more than once. This is needed because Commanded event handlers guarantee at-least-once event delivery (an event can be received more than once). However the after_update/3 function will still be called when the idempotency check fails due to receiving an already projected event. In this case it should not be called.

y86 commented

@slashdotdash this issue seems to be solved already. This is the code we have when calling after_update:

        with %Ecto.Multi{} = multi <- apply(multi_fn, [multi]),
             {:ok, changes} <- transaction(multi) do
          if function_exported?(__MODULE__, :after_update, 3) do
            apply(__MODULE__, :after_update, [event, metadata, changes])
          else
            :ok
          end
        else
          {:error, :verify_projection_version, :already_seen_event, _changes} -> :ok
          {:error, _stage, error, _changes} -> {:error, error}
          {:error, _error} = reply -> reply
        end

the with clause + {:error, :verify_projection_version, :already_seen_event, _changes} -> :ok should do the job, right?

Yes, it looks as though it already works as expected, no change necessary.