Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jan 30 2019 14:49
    slashdotdash edited #169
  • Jan 30 2019 14:48
    Freyskeyd commented #249
  • Jan 30 2019 14:48
    Freyskeyd closed #249
  • Jan 30 2019 10:28
    slashdotdash commented #249
  • Jan 30 2019 09:08
    Freyskeyd commented #249
  • Jan 29 2019 11:37
    Freyskeyd commented #187
  • Jan 29 2019 11:34
    Freyskeyd synchronize #249
  • Jan 29 2019 10:50
    Freyskeyd synchronize #249
  • Jan 29 2019 10:16
    slashdotdash closed #231
  • Jan 29 2019 10:16
    slashdotdash commented #231
  • Jan 29 2019 09:48
    Freyskeyd commented #231
  • Jan 29 2019 09:10
    Freyskeyd synchronize #249
  • Jan 28 2019 15:49
    Freyskeyd edited #249
  • Jan 28 2019 15:32
    Freyskeyd synchronize #249
  • Jan 28 2019 15:04
    Freyskeyd opened #249
  • Jan 28 2019 11:20
    imetallica closed #119
  • Jan 28 2019 11:20
    imetallica commented #119
  • Jan 28 2019 10:40
    Freyskeyd commented #119
  • Jan 28 2019 10:40
    slashdotdash commented #184
  • Jan 28 2019 10:39
    Freyskeyd commented #52
Bruno Castro
@brunohkbx

Thanks. I've been trying to set up Phoenix.PubSub.Redis as the adapter. but no luck so far.
It works locally but on heroku its throwing this error everytime:

Mon Apr 26 2021 16:19:54 unable to establish initial redis connection. Attempting to reconnect... metadata
Mon Apr 26 2021 16:19:57 failed to publish broadcast due to closed redis connection metadata

Its coming from this process: CommandedApp.PhoenixPubSub.Tracker_shard0

Config:

pubsub: [
      phoenix_pubsub: [
        url: System.fetch_env!("REDIS_URL"),
        node_name: System.get_env("HEROKU_DYNO_ID", "default"),
        pool_size: String.to_integer(System.get_env("REDIS_POOL_SIZE", "10"))
      ]
    ]

Thanks in advance :smile:

Bruno Castro
@brunohkbx
I'm also starting another Phoenix.PubSub.Redis in the application. I don't know if its conflicting with commanded but it works locally.
  {Phoenix.PubSub,
   name: MyApp.PubSub,
   adapter: Phoenix.PubSub.Redis,
   url: redis_config[:url],
   node_name: redis_config[:node_name]},
Bruno Castro
@brunohkbx
just in case someone wonders why the problem was about the runtime configuration. moving everything under the init/1 function fixed it.
Tomek Rybczyński
@rybex
Hello everyone :) Quick question. Is there any option to load manually all events event store? I have events list in a file and I would import all of them to my commanded app. I will be grateful for any hints
Günter Glück
@gugl_twitter
@rybex That recipe could be a good starting point for you: commanded/recipes#14
Tomek Rybczyński
@rybex
@gugl_twitter thx. I will try that :+1:
Jonathan Stiansen
@jonathanstiansen
Hey guys! probably a question that is painfully obvious for most people who understand the in's and out's of commanded - can you share bounded contexts across projects? How do you go about doing that? My initial thought is that it's just the router you'd need to add, and the rest is all in one sub context
Also does anyone use property based testing with commanded? Anything that stands in your way to doing so?
Ben Smith
@slashdotdash
@jonathanstiansen I’ve written an article outlining the various ways you can structure an Elixir application using Commanded: https://10consulting.com/2021/03/18/commanded-application-architecture/
The simplest is to have a single global Commanded Application and EventStore.
You can then define a Commanded router per context and include them in the top-level Commanded Application
defmodule MyApp.App do
  use Commanded.Application,
    otp_app: :my_app,
    event_store: [
      adapter: Commanded.EventStore.Adapters.EventStore,
      event_store: MyApp.EventStore
    ]

  router(MyApp.ContextA.Router)
  router(MyApp.ContextB.Router)
  router(MyApp.ContextC.Router)
  # … etc
end
Jonathan Stiansen
@jonathanstiansen
Nice. That makes sense, I'm thinking (probably incorrectly) about rails engines - and how across apps we may choose to compose different ES systems from the same domains
This seems like it could be a nice solution, the only thing I'd need to redo is the controller level stuff which is great! :-)
Giorgi Kavrelishvili
@grkek
@slashdotdash why is commanded so fucking slow with many
requests
and commands?
Ben Smith
@slashdotdash
@grkek Are you asking for my help, or venting your frustration?
Giorgi Kavrelishvili
@grkek
Both :D
How does one improve the performance of Commanded?
Ben Smith
@slashdotdash

It’s difficult to give guidance without knowing exactly what your domain is. Usually you want to design small, short lived aggregates with few events in their lifetime.

You can partition your application by service, context, tenant, etc. to improve performance by using a separate Commanded Application and EventStore for each. This will help to distribute load, processing, and event store read/writes.

I’ve written up the various architectural choices available.

https://10consulting.com/2021/03/18/commanded-application-architecture/

If you can identify a particular bottleneck in Commanded itself then that can be looked into.
Ben Smith
@slashdotdash
Dispatching commands with consistency: :strong will add latency if used due to blocking until the event(s) have been handled by any configured event handlers. The default event consistency is recommended for low latency.
Tomek Rybczyński
@rybex
@gugl_twitter Hi. Thanks for your previous tip. It helped a lot :) I have one more question. How to check Commanded.ProcessManagers.ProcessManager state? Do you have any example of how to load process manager state locally?
Günter Glück
@gugl_twitter
@rybex Glad it helped. For debugging purposes or something like that?
Tomek Rybczyński
@rybex
@gugl_twitter yes debugging only :)
Günter Glück
@gugl_twitter
@rybex I see. Unfortunately I never tried that but you could try to find a way to start/get the https://github.com/commanded/commanded/blob/master/lib/commanded/process_managers/process_manager_instance.ex you want to investigate state for and find a way to use the process_state function on it but it might be easier to use the telemetry for it. Maybe that is a useful pointer and the better way to go for it: test/process_managers/process_manager_telemetry_test.exs I think I would follow the telemetry path for debugging purposes.
narayan iyer
@iyerland
@slashdotdash When is an aggregate removed from memory (or persisted) and what is done to get it back in memory? Do you re-play all the events in the event_store to re-construct the aggregate?
Ben Smith
@slashdotdash

Aggregate instances persist in memory indefinitely unless you implement the Commanded.Aggregates.AggregateLifespan behaviour.

https://hexdocs.pm/commanded/Commanded.Aggregates.AggregateLifespan.html

An instance is started and its state is rebuilt from either a state snapshot + new events or all historical events on demand when a command is dispatched to it.

narayan iyer
@iyerland
Thanks @slashdotdash
Tomek Rybczyński
@rybex
@gugl_twitter Thx for your response :) I will try that
Marcelo Dominguez
@marpo60
Is it possible to add and remove middleware dynamically?
Ben Smith
@slashdotdash
Not currently as the middleware is configured at compile-time, so it is fixed
But I dont want to add that middleware in the production code, only on some tests.
Ben Smith
@slashdotdash
You could use a compile-time conditional to include the middleware only when the env is :test (configured in config/test.exs):
if Application.compile_env(:my_app, :env) == :test do
  middleware CommandAuditMiddleware
end
# config/test.exs
config :my_app, env: :test
Or use a similar environment check inside the middleware module / functions
Marcelo Dominguez
@marpo60
yeah, that would work.
Thanks Ben for the help and the fast reply!
Ben Smith
@slashdotdash
def before_dispatch(pipeline, env \\ Application.compile_env(:my_app, :env))
def before_dispatch(pipeline, :test) do
  # auditing

  pipeline
end
def before_dispatch(pipeline, _env), do: pipeline
mlchai
@mlchai
sorry if this is a dumb question (new to ES and commanded) but if I wanted an aggregate root to talk to other aggregates (check their state or send messages to them to emit events) what would be the best way of doing something like that?
Daniel Drexler
@aeturnum

Hey there - I'm trying to get a basic commanded setup and I'm getting a confusing error at the eventstore <-> postgrex connection in a basic test:

The full gory traceback is available here, but it's happening after an aggregate returns an event to be stored in postgres.

It seems to be failing to match on this line of (appender.ex)[https://github.com/commanded/eventstore/blob/master/lib/event_store/storage/appender.ex]:
%Postgrex.Error{postgres: %{code: error_code, constraint: constraint}} = error

The Postgres.Error.postgres map does not have a :constraint field

Does this ring any bells for folks?

(commanded 1.2.0, commanded_eventstore_adapter 1.2.0, evenstore 1.3.1, postgrex 0.15.9)

lee eggebroten
@leggebroten

There's a pretty common Use Case that I'm not finding a "clean" solution for. I've a simple Commanded change in mind, but am tossing this out to see if I'm missing something obvious ...

Use Case:
a) For any given Command, notify external client(s) whenever any of the Events produced by the Handler alters the Aggregate's state
b) ONLY ONE notification can be emitted regardless of the number of that Command's Events which alter Aggregate state.
c) NO notification can be emitted if the Command's Events made no changes to the Aggregate
d) The notification should be provided with the Aggregate's delta produced by the Command Handler's Events.

Observations:

  • (The most basic ...) Events notify a set of Listeners/Subscribers that "something happened"
  • A subclass of Events change an Aggregate's state. Mutators.
  • This Use Case is illustrating another sub-class of Event that plays the initiator role in the Observer pattern. For clarity I'll refer to them as "Observers" even though they're not themselves Observers. (I don't have a better name for this role they're playing)
  • For the pattern to work an Observer cannot also be a Mutator
  • The ordering of Mutator Events is important.
  • The ordering of Observer Events is irrelevant so long as they follow all Mutator Events.

There are three architecturally clumsy solutions I've thought of (none of which can meet d):
1) Specifically append an Observer Event at the end of every Handler which has one or more Mutator Events. This means the Handler is Coupled to the implementation details of all its listed events. A fragile solution vulnerable to any changes to Events (or require costly tests).
2) Delegate to the Mutator modules the task of appending Observer Events Unfortunately, to meet b, this would require Coupling Events with its siblings (to avoid sending multiple notifications)
3) An Event Handler or Process Manager could somehow trigger the notification, but there's no means of detecting when all the Events from a particular Command have finished meaning this would likely not be able to meet b.

Thoughts?

Ben Smith
@slashdotdash
@aeturnum Which version of Postgres are you using? You might need to upgrade to v10 or newer.
Ben Smith
@slashdotdash
@leggebroten You could have the aggregate emit a StateChanged event whenever the state is mutated by the events produced from a command by comparing the aggregate state before and after the command’s event(s) have been applied. You may be able to to use the Commanded.Aggregate.Multi approach here. The StateChanged event could contain fields with the state before and after or you could determine what has changed and include a delta.
The benefit of using an event is that it gets included in the event log as an immutable fact. Great for auditing/debugging
lee eggebroten
@leggebroten

@slashdotdash
Thanks for getting back to me.
Emitting a StateChanged event is what I'm doing now. Works but is kinda clunky 'cause the Command Handler has to know that one or more of the Events it's emitting will induce a state change.

Not the end of the world ...

Tran Manh Linh
@manhtranlinh
Hi all, I have just found a issues:
if I config in confix.exs the parameter "config :commanded, default_consistency: :strong", it work exactly and I can query the read model after dispatch command return :ok
But if I use consistency: :strong option in dispatch command directly, although dispatch return :ok but it will not work smoothly: few cases work, few cases fail, because the query to read model run before projection complete.
Benjamin Moss
@drteeth
You have to include consistency: strong on each read model you want to be strong as well as dispatch the command with the strong option
@manhtranlinh ^^