gregjohnson

gregjohnson

Commanded: Wait for an event handler based on aggregate_version

Hi, the " Dispatch returning aggregate version" section of Commanded docs includes:

“You can optionally choose to include the aggregate’s version as part of the dispatch result …
This is useful when you need to wait for an event handler … to be up-to-date before continuing execution or querying its data.”

Does anyone have any hints as to the best way to use the aggregate version as a method for waiting for an event handler to be up-to-date? (and/or any use case comparisons with using consistency :strong)

Thanks …

First Post!

drteeth

drteeth

Hello @gregjohnson,

Come join us on the Elixir Slack: https://elixir-lang.slack.com/ in the #commanded channel if you are looking for more timely help. There are a number of us there.

If you are wanting to wait for an event handler to catch up to a particular event, one way to do it would be to publish an event over PubSub and wait for that event before moving on.

As an example, say you want to dispatch an OrderWidget command and wait for your OrderHandler to project an OrderSummary record for a corresponding WidgetOrdered event. For the example the order is received via a REST API controller:

defmodule Foo.OrderController do
  def create(conn, order_params) do
    # listen for all order summary events
    Phoenix.PubSub.subscribe(Foo.PubSub, "order_summaries")

    # dispatch the command
    {:ok, %{aggregate_version: version}} =
      Foo.CommandedApp.dispatch(command, include_execution_result: true)

    # wait for the handler to process up to the event
    receive do
      {:order_summarized, v} when v >= version ->
        # the handler has run at least as far as we want
        # query for the summary and return a result
    after
      5000 ->
        # we've waited long enough
        # tell the caller that we accepted their order, but
        # we're having trouble... =(
    end 

    # we're done listening for events
    Phoenix.PubSub.unsubscribe(Foo.PubSub, "order_summaries")
  end
end

The handler might look something like:

defmodule Foo.OrderHandler
  use Commanded.Event.Handler,
    application: Foo.CommandedApp,
    name: "OrderHandler"

  def handle(%WidgetOrdered{} = event, metadata) do
    # write the OrderSummary record to the database
    summary = ...

    # broadcast over pubsub that we've handled this event
    Phoenix.PubSub.broadcast(Foo.PubSub, "order_summaries", {:order_summarized, metadata.stream_version})

    :ok
  end

You could use strong consistency as mentioned in the docks, but that try to avoid that where possible.

Finally, you might also try to get away with returning the input params as result: if you have successfully dispatched the command, then we know the input params were good:

defmodule Foo.AddressController do
  def update(conn, %{"id" => id, "street" => street, "city" => city}) do
    command = %ChangeAddress{address_id: id, street: street, city: city}
   :ok = Foo.CommandedApp.dispatch(command)

   # we know street and city have been accepted, so we can safely return them
   json(conn, %{address_id: id, street: street, city: city})
 end
end

Where Next?

Popular in Questions Top

gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement