View Source Changelog

v1.4.3

Enhancements

  • Use Logger.warning to fix deprecation warnings (#542).
  • Add typespec to CompositeRouter.dispatch/2 function (#536).
  • Support opts in Commanded.EventStore.append_to_stream function (#528).
  • Process manager metadata access (#514).

Bug fixes

  • Correct parameter type in ProcessManager.after_command/1 callback function (#533).

v1.4.2

v1.4.1

Enhancements

  • Retry command execution when the aggregate process is down (#494).

Bug fixes

  • Remove duplicate apply function call when receiving missed events published to an aggregate's event stream (364c877).
  • Fix typespec typo in Commanded.Application (#503).

v1.4.0

Enhancements

  • Allow a process manager to stop after dispatching a command (#460).
  • Replace use Mix.Config with import Config in config files (#467).
  • Event handler concurrency (#486).
  • Remove elixir_uuid dependency (#493).
  • Support and test for OTP 25 (#489).

v1.3.1

Bug fixes

  • Event Handler not calling init/1 callback function on restart (#463).
  • Call process manager init/1 function on process restart (#464).

v1.3.0

Enhancements

  • Allow command identity to be provided during dispatch (#406).
  • Define Commanded.Telemetry module to emit consistent telemetry events (#414).
  • Telemetry [:commanded, :aggregate, :execute] events (#407).
  • Telemetry [:commanded, :event, :handle] events (#408).
  • Telemetry [:commanded, :process_manager, :handle] events (#418).
  • Telemetry [:commanded, :application, :dispatch] (#423).
  • Graceful shutdown of event handlers (#431).
  • Ensure command dispatch metadata is a map (#432).
  • Retry command execution on node down (#429).
  • Dispatch returning resultant events (#444).
  • Get aggregate state (#448).
  • Support telemetry v1.0 (#456).

v1.2.0

Enhancements

  • Add init/1 callback function to event handlers and process managers (#393).
  • Include application and handler_name as additional event handler metadata (#396).
  • Allow GenServer start options to be provided when starting event handlers and process managers (#398).
  • Add hibernate_after option to application config (#399).
  • Add support for providing adapter-specific event store subscription options (#391).
  • Support custom state for event handlers (#400).
  • Allow event handlers and process manager error callback to return failure context struct (#397).
  • Allow a before execute function to be defined which is called with the command dispatch execution context and aggregate state before (#402).

Bug fixes

  • Allow process manager error/3 callback to return :skip for failed commands, not just failed events (#362).

v1.1.1

Enhancements

  • Capture exception on Process Manager apply/2 and call error/3 callback functions (#380).
  • Include metadata in upcaster protocol (#389).

Bug fixes

v1.1.0

Enhancements

  • Dynamic Commanded applications (#324).
  • Log and ignore unexpected messages received by event handlers and process manager instances (#333)
  • Process manager identity/0 function (#334).
  • Extend Commanded.AggregateCase ExUnit case template to support Commanded.Aggregate.Multi.
  • Allow Commanded.Aggregate.Multi to return events as :ok tagged tuples.
  • Run the formatter in CI (#341).
  • Add stacktraces to EventHandler error logging (#340)
  • refute_receive_event/4 only tests newly created events (#347).
  • Allow Commanded Application name to be set dynamically in middleware (#352).
  • Remove router module compile-time checking (#363).
  • Reduce memory consumption during aggregate state rebuild (#368).
  • Upgrade to phoenix_pubsub to 2.0 (#365).
  • Ignore :not_found error when resetting InMemory event store (#354).
  • Add router/1 to locals_without_parens in Mix format config (#351).
  • Include stacktrace in event handler and process manager error callback functions (#342).
  • Call event handler's error/3 callback function when handle/2 function returns an invalid value (#372).

Bug fixes

  • Fixes the typespec for command dispatch (#325).
  • Process manager stops if interested?/1 returns an empty list (#335).

v1.0.1

Enhancements

  • Global registry using Erlang's :global module (#344).
  • Command dispatch return (#331).

Bug fixes

  • Fix distributed subscription registration bug (#345).
  • Retry event handler and process manager subscriptions on error (#348).

v1.0.0

Breaking changes

  • Support multiple Commanded apps (#298).

Enhancements

  • Define adapter behaviour modules for event store, pubsub, and registry (#311).
  • Add AggregateCase ExUnit case template to support aggregate unit testing (#315).
  • Application config lookup (#318).

Bug fixes

  • Fix process manager exception on start (#307).
  • Fix commanded aggregate race (#308).
  • Fix Dialyzer warnings and include in Travis CI (#317).

Upgrading

Follow the upgrade guide to define and use your own Commanded application.


v0.19.1

Enhancements

  • Reset event handler mix task mix commanded.reset MyApp.Handler (#293).

Bug fixes

  • Fix regression in Commanded.Middleware.Logger.delta (#295).

v0.19.0

Enhancements

  • Update typespec for data and metadata fields in Commanded.EventStore.EventData struct (#246).
  • Add include_execution_result and aggregate_version to typespec for router command dispatch (#262).
  • Add .formatter.exs to Hex package (#247).
  • Event upcasting (#263).
  • Support :ok tagged tuple events from aggregate (#268).
  • Modify Commanded.Registration.start_child to pass a child_spec (#273).
  • Add supervisor_child_spec/2 to Commanded.Registration behaviour (#277) used by Commanded Horde Registry.
  • Ensure Commanded can be compiled when optional Jason dependency is not present (#286).
  • Fix Aggregate initialization races (#287).
  • Support {:system, varname} format in Phoenix PubSub config (#291).

Breaking changes


v0.18.1

Enhancements

  • Process manager idle process timeout (#290).
  • Register event handler and process manager subscriptions on process start (#272).

v0.18.0

Enhancements

  • Rename uuid dependency to elixir_uuid (#178).
  • Allow aggregate identity to be of any type that implements the String.Chars protocol (#166).
  • Process manager and event handler error & exception handling (#192).
  • Process manager event handling timeout (#193).
  • Allow event handlers to subscribe to individual streams (#203).
  • Add new values for expected_version for event store append events behaviour (#127).
  • Export Commanded.Commands.Router macros in .formatter.exs file (#204).
  • Generate specs and docs for Router dispatch functions only once (#206).
  • Allow two-arity predicate function in wait_for_event receiving both event data and recorded event struct (#213).
  • Allow :infinity timeout on command dispatch (#227)
  • Strict process manager routing (#243).
  • Allow Commanded.Aggregate.Multi to be nested (#244).
  • Add child_spec/0 function to Commanded.EventStore behaviour.
  • Add delete_subscription/2 to Commanded.EventStore behaviour (#245).
  • Add refute_receive_event/2 to Commanded.Assertions.EventAssertions test helpers.

Bug fixes

Breaking changes

  • Migrate to Jason for JSON serialization (#234).

    You will need to add Jason as a dependency in mix.exs:

    defp deps do
      [{:jason, "~> 1.2"}]
    end

    Jason has no support for encoding arbitrary structs - explicit implementation of the Jason.Encoder protocol is always required. You must update all your domain event modules, aggregate state (when using state snapshotting), and process manager state to include @derive Jason.Encoder as shown below:

    defmodule AnEvent do
      @derive Jason.Encoder
      defstruct [:field]
    end
  • Extend aggregate lifespan behaviour to include after_error/1 and after_command/1 callbacks (#210).

    Previously you only had to define an after_event/1 callback function to implement the Commanded.Aggregates.AggregateLifespan behaviour:

    defmodule BankAccountLifespan do
      @behaviour Commanded.Aggregates.AggregateLifespan
    
      def after_event(%BankAccountClosed{}), do: :stop
      def after_event(_event), do: :infinity
    end

    Now you must also define after_command/1 and after_error/1 callback functions:

    defmodule BankAccountLifespan do
      @behaviour Commanded.Aggregates.AggregateLifespan
    
      def after_event(%BankAccountClosed{}), do: :stop
      def after_event(_event), do: :infinity
    
      def after_command(%CloseAccount{}), do: :stop
      def after_command(_command), do: :infinity
    
      def after_error(:invalid_initial_balance), do: :stop
      def after_error(_error), do: :stop
    end

Upgrading

Please ensure you upgrade the following event store dependencies.

Using the Elixir EventStore:

Using EventStoreDB:

  • commanded_extreme_adapter to v0.6.0

Commanded Ecto projections:

  • commanded_ecto_projections to v0.8.0

Commanded scheduler:


v0.17.5

Enhancements

  • Process manager idle process timeout (#290).

v0.17.4

Bug fixes

  • Register event handler and process manager subscriptions on process start (#272).

v0.17.3

Bug fixes

  • Fix snapshot recording (#196).
  • Fixed warning about deprecated time unit in elixir 1.8 (#239).

v0.17.2

Enhancements

  • Remove default error/4 callback function from process manager to silence deprecation warning.

v0.17.1

Enhancements

Bug fixes

  • Set default aggregate lifespan timeout to :infinity (#200).

v0.17.0

Enhancements

  • Ability to globally override include_execution_result and include_aggregate_version in environment config (#168).
  • Handle custom type serialization in snapshot source type (#165).
  • Fix compiler warnings in generated code (routers, event handlers, and process managers).
  • Add InMemory.reset!/0 for testing purposes (#175).

Bug fixes

  • Ensure process managers can be configured with :strong consistency.
  • Fix error when subscription process already tracked (#180).

v0.16.0

  • Support composite command routers (#111).
  • Aggregate state snapshots (#121).
  • New error/3 callback for process manager and deprecated error/4 (#124)
  • Router support for identity prefix function.
  • Retry command execution on concurrency error (#132).
  • Event handler error/3 callback (#133).
  • Support distributed dispatch consistency (#135).
  • Defer event handler and process router init until after subscribed (#138).
  • Replace aggregate lifespan after_command/1 callback with after_event/1 (#139).
  • Support process manager routing to multiple instances (#141).
  • Allow a default consistency to be set via the application env (#150).
  • Command dispatch consistency using explicit handler names (#161).

Breaking changes

  • The Commanded.Aggregates.AggregateLifespan behaviour has been changed from after_command/1 to after_event/1. You will need to update your own lifespan modules to use events instead of commands to shutdown an aggregate process after an inactivity timeout.

Upgrading

Please ensure you upgrade the following event store dependencies.

Using the Elixir EventStore:

Using EventStoreDB:

  • commanded_extreme_adapter to v0.5.0

v0.15.1

Bug fixes

  • Event handler child_spec/1 must include config options defined by use macro.

v0.15.0

Enhancements

  • Process manager command dispatch error handling (#93).
  • Event handlers may define an init/0 callback function to start any related processes. It must return :ok, otherwise the handler process will be stopped.
  • Add include_execution_result option to command dispatch (#96).
  • Add Commanded.Aggregate.Multi (#98) as a way to return multiple events from a command dispatch that require aggregate state to be updated after each event.
  • Correlation and causation ids (#105).
  • Initial support for running on a cluster of nodes (#80).

Bug fixes

  • Adding a prefix to the aggregate in the router breaks the strong consistency of command dispatch (#101).

Upgrading

Please ensure you upgrade the following event store dependencies.

Using the Elixir EventStore:

Using EventStoreDB:

  • commanded_extreme_adapter to v0.4.0

v0.14.0

Enhancements

  • Dispatch command with :eventual or :strong consistency guarantee (#82).
  • Additional stream prefix per aggregate (#77).
  • Include custom metadata during command dispatch (#61).
  • Validate command dispatch registration in router (59).

Upgrading

Please ensure you upgrade the following event store dependencies.

Using the Elixir EventStore:

Using EventStoreDB:

  • commanded_extreme_adapter to v0.3.0

v0.13.0

Enhancements

  • Command dispatch optionally returns aggregate version, using include_aggregate_version: true during dispatch.

v0.12.0

Enhancements


v0.11.0

Enhancements

  • Shutdown idle aggregate processes (#43).

v0.10.0

Enhancements

  • Extract event store integration to a behaviour (Commanded.EventStore). This defines the contract to be implemented by an event store adapter. It allows additional event store databases to be used with Commanded.

    By default, a GenServer in-memory event store adapter is used. This should only be used for testing as there is no persistence.

    The existing PostgreSQL-based eventstore integration has been extracted as a separate package (commanded_eventstore_adapter). There is also a new adapter for Greg Young's Event Store using the Extreme library (commanded_extreme_adapter).

    You must install the required event store adapter package and update your environment configuration to specify the :event_store_adapter module. See the README for details.


v0.9.0

Enhancements

  • Stream events from event store when rebuilding aggregate state.

v0.8.5

Enhancements

  • Upgrade to Elixir 1.4 and remove compiler warnings.

v0.8.4

Enhancements

  • Event handler and process manager subscriptions should be created from a given stream position (#14).
  • Stop process manager instance after reaching its final state (#24).

v0.8.3

Enhancements

  • Middleware after_failure callback is executed even when a middleware halts execution.

v0.8.2

Bug fixes

  • JsonSerializer should ensure event type atom exists when deserializing (#28).

v0.8.1

Enhancements

  • Command handlers should be optional by default (#30).

v0.8.0

Enhancements

  • Simplify aggregates and process managers (#31).

v0.7.1

Bug fixes

  • Restarting aggregate process should load all events from its stream in batches. The Event Store read stream default limit is 1,000 events.

v0.7.0

Enhancements

  • Command handling middleware allows a command router to define middleware modules that are executed before, and after success or failure of each command dispatch (#12).

v0.6.3

Enhancements

  • Process manager instance processes event non-blocking to prevent timeout during event processing and any command dispatching. It persists last seen event id to ensure events are handled only once.

v0.6.2

Enhancements

  • Command dispatch timeout. Allow a timeout value to be configured during command registration or dispatch. This overrides the default timeout of 5 seconds. The same as the default GenServer call timeout.

Bug fixes

  • Fix pending aggregates restarts: supervisor restarts aggregate process but it cannot accept commands (#22).

v0.6.1

Enhancements

  • Upgrade eventstore mix dependency to v0.6.0 to use support for recorded events created_at as NaiveDateTime.

v0.6.0

Enhancements

  • Confirm receipt of events in event handler and process manager router (#19).
  • Convert keys to atoms when decoding JSON using Poison decoder.
  • Prefix process manager instance snapshot uuid with process manager name.
  • Multi command dispatch registration in router (#16).

v0.5.0

Enhancements

  • Include event metadata as second argument to event handlers. An event handler must now implement the Commanded.Event.Handler behaviour consisting of a single handle_event/2 function.

v0.4.0

Enhancements

  • Macro to assist with building process managers (README).

v0.3.1

Enhancements

  • Include unit test event assertion function: assert_receive_event/2 (#13).
  • Include top level application in mix config.

v0.3.0

Enhancements

  • Don't persist an aggregate's pending events when executing a command returns an error (#10).

Bug fixes

  • Ensure an aggregate's pending events are persisted in the order they were applied.

v0.2.1

Enhancements

  • Support integer, atom or strings as an aggregate UUID (#7).

v0.1.0

Initial release.