Comments (11)
@drozzy By default Commanded will set the event type to the event module's full namespace (prepended with Elixir.
). This behaviour is implemented in the Commanded.Serialization.ModuleNameTypeProvider
module, as shown below:
defmodule Commanded.Serialization.ModuleNameTypeProvider do
@moduledoc """
A type provider that uses the Elixir module name
Example:
- %An.Event{} module mapped to "Elixir.An.Event".
"""
@behaviour Commanded.EventStore.TypeProvider
def to_string(struct), do: Atom.to_string(struct.__struct__)
def to_struct(type) do
type |> String.to_existing_atom() |> struct()
end
end
You can write your own type name provider by implementing the Commanded.EventStore.TypeProvider
behaviour in your own module. It's only two functions: to_string/1
and to_struct/1
.
As an example, you could use just the event module name, excluding the namespace:
defmodule ExampleTypeProvider do
@behaviour Commanded.EventStore.TypeProvider
def to_string(%Elixir.Foo.Events.BurgerRequested{}), do: "BurgerRequested"
def to_struct("BurgerRequested"), do: %Elixir.Foo.Events.BurgerRequested{}
end
Then configure it in your environment config file (config/config.exs
):
config :commanded,
type_provider: ExampleTypeProvider
I'm not entirely sure of your exact use case but events should be deserialized to the same module they were serialized from. Perhaps you need to separate the event modules into their own library or umbrella app to be referenced by both nodes (e.g. myapp_events
or myapp_contracts
)?
The events are the contracts for your application so it is acceptable to extract them into their own app to support shared use.
Does that help you out?
from commanded.
Yes, this solves my issue completely.
Thank you.
P.S.: To answer you question about my use case: I'm not using umbrella apps. Instead, I actually have separate nodes doing rpc-calls to each other. They communicate through event-store events as a means for pub-sub. That is why I need to deserialize them in a different name space.
from commanded.
Hm.. are you sure the config is right with type_provided
key?
I did everything but no change in behavior...
from commanded.
Sorry @drozzy, I forgot to say that you need to recompile Commanded after changing this config setting. It's compiled into Commanded using a macro. The config setting is type_provider
.
You need to run:
$ mix deps.compile commanded --force
Let me know if that still doesn't work.
from commanded.
When I do this compile I get this really weird error:
warning: function ModelAR.TypeProvider.to_struct/1 is undefined (module ModelAR.TypeProvider is not available) lib/commanded/serialization/json_serializer.ex:25
Even though I have a module ModelAR.TypeProvider
in the file type_provider.ex
.
Here is my config:
config :commanded,
event_store_adapter: Commanded.EventStore.Adapters.Extreme,
type_provider: ModelAR.TypeProvider
Now, it's probably me making some sort of typo, so I'll keep debugging. But maybe something jumps out at you?
from commanded.
Keeps saying it's not defined. I do pretty much the same thing as in the standard type provider:
from commanded.
Yes, I've just tried to reproduce this and have encountered the same compilation error. The good news is that it does actually work when you run your application.
I used the following type provider module which excludes the Elixir.
prefix from type name:
defmodule ExampleTypeProvider do
@behaviour Commanded.EventStore.TypeProvider
def to_string(struct) do
"Elixir." <> type = Atom.to_string(struct.__struct__)
type
end
def to_struct(type) do
"Elixir." <> type |> String.to_existing_atom() |> struct()
end
end
Peeking into the events
table I can see it using the provider I've specified above (as there's no Elixir.
prefix on any event_type
values). I also included logging just to prove it was using my own module and saw output in the console when appending events to a stream.
I'll have a think about how best to suppress that warning.
from commanded.
Yap! It works. Thanks.
from commanded.
P.S.: Just out of curiosity (and not being an expert in Elixir) why are you using macros?
from commanded.
In this case it's only used for performance reasons. Reading the value from the application configuration is done once, at compile time, and not each time an event is (de)serialized.
I'm reconsidering this approach now due to it not being very user friendly.
from commanded.
Compared to read-times over the network, deserialization etc.. I think this is still going to be very fast, even if you read it anew every time.
But that's just my 2c haha.
from commanded.
Related Issues (20)
- Process manager router option not working
- Lessons learned from performance optimization - an unlikely culprit HOT 3
- no function clause matching in Commanded.Commands.Dispatcher.telemetry_stop/3 HOT 1
- Docs questions
- Stacktrace in event handler error? HOT 2
- Paralelization Strategies in EventHandlers
- Should Commanded.Event.Handler support messages from swarm? HOT 2
- Event retention policies?
- please support multiple commanded application with one eventstore HOT 6
- Process Manager state serialization breaks when using a custom TypeProvider with the JsonSerializer
- `Commanded.ProcessManagers.ProcessManager.identity/0` function returns `nil` in unit tests
- no function clause matching in Commanded.Event.Handler.partition_event/4 HOT 1
- EventstoreDB is sunsetting the TCP protocol HOT 1
- Is it a bad practice for an event handler to depend on a projector completion? HOT 2
- Snapshotting 2 Aggregates having same identity
- Is it possible to log contents of InMemoryEventStore on failed test?
- Ecto Sandbox, Projections and In Memory adapter HOT 3
- Aggregate throws error when execute returns more than 1000 events.
- Individual stream events handling HOT 1
- Skipped event with concurrency enabled HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from commanded.