Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    rgafken-pillar
    @rgafken-pillar
    Oh, it's just that simple? Well that's easy, lol
    Frank Ebersoll
    @frankebersoll
    The real issue is that Mongo DB just creates an index itself and uses it, and it all works as long as it isn't used in production
    As soon as there is some load on the application, you get duplicate ids.
    rgafken-pillar
    @rgafken-pillar
    I'm not sure what exactly you mean
    Frank Ebersoll
    @frankebersoll
    Well, you used EventFlow and MongoDb and everything worked, and it looks like a bug that you get duplicate IDs
    It should throw an exception if there is no Index
    rgafken-pillar
    @rgafken-pillar
    Oh, this took me a minute, you were saying it works fine without an index outside of production! I thought you were saying the index wouldn't work in prod :thumbsup:
    Frank Ebersoll
    @frankebersoll
    I meant you just don't notice it outside any load
    rgafken-pillar
    @rgafken-pillar
    makes sense! Thanks a bunch!
    Frank Ebersoll
    @frankebersoll
    You're welcome
    Alexander Chervony
    @alexander-chervony
    hi @rasmus ! could you please clarify if the framework can be naturally used without async/await in simplistic syncronous style?
    the thing is that I want to use it on realy low load small user amount app where asyncs just adds unnecessary code bulkiness without real benefits
    Frank Ebersoll
    @frankebersoll
    Not rasmus, but maybe I can still answer. Just use it synchronously and put „return Task.CompletedTask“ at the end of methods?
    Alexander Chervony
    @alexander-chervony
    thank you for the reply, but it seems not really elegant approach - code bulkiness of asyncs stays in place and does nothing
    Frank Ebersoll
    @frankebersoll
    You might create a custom CommandBase<TAgg,TId,TCmd> with a synchronous Execute method?
    You just delegate the call from the async to the non-async method.
    That‘s two minutes of work and there you have your elegant approach.
    Alexander Chervony
    @alexander-chervony
    thanks a lot! sounds better, do you have an idea how much more classes I need to override/replace in order to have everything working as intended in sync way? or just CommandBase?
    Frank Ebersoll
    @frankebersoll
    Well, it‘s the only place where usually all calls wouldn‘t profit of async.
    As there is no I/O
    Alexander Chervony
    @alexander-chervony
    great, I'll try, thanks!!
    Frank Ebersoll
    @frankebersoll
    Everything else might trigger Infrastructure code:
    There are synchronous subscribers (which still have an async signature)
    But you use them to not only do computations, but also update state somewhere. Usually involving I/O
    Everything involving I/O should use async-await: DB access, File System, Networking.
    Alexander Chervony
    @alexander-chervony
    well I doubdt that it always beneficial in networking. for example in my case sync controller actions will do just fine (small amount of users)
    Frank Ebersoll
    @frankebersoll
    It‘s just best practice to use the async methods over sync methods if there are any.
    But at the end it‘s your code 🙂
    Alexander Chervony
    @alexander-chervony
    ok, thanks a lot))
    Rasmus Mikkelsen
    @rasmus
    @alexander-chervony sorry for the late reply, but if your application is .NET Core you can simply use the .Result or .Wait methods on the tasks. If it isn't, then you can use the static class AsyncHelper to help prevent deadlock in e.g. ASP.NET and WPF applications. Weather or not you are in risk of getting deadlocks depends on the sync context. It's definitely better to do async all the way though.
    Alexander Chervony
    @alexander-chervony
    OK, Rasmus, got your point, thank you!
    Rasmus Mikkelsen
    @rasmus
    There's a test in the EventFlow code base that illustrates a deadlock
    In the AsyncHelperTests I think
    You'll have to run it manually as it does a deadlock.
    Alexander Chervony
    @alexander-chervony
    also @rasmus could you please clarify: https://cqrs.nu/Faq - as I understand here Entity is referred as part of write model or aggregate (that gets persisted), but in Shipment example entities used solely for read model
    isn't it a controversy, or I got something wrong?
    Rasmus Mikkelsen
    @rasmus

    What you use them for is up to you. The equality of an entity is defined by its ID, thus if the ID is the same its the same object, even if the properties are different (might just be from different points in time). This is different from value objects for which all properties needs to be the same before they are considered equal.

    The shipping domain example within the source code is very limited and only has a few scenarios built-in. In the few examples that there are, the entities are used as a materialized read-only version of the aggregates that can be passed to others. Updates to aggregates are done trough services.

    I guess you could use entire entities for write as well, but then you'll have to calculate the "diff" between the entity state and the actual aggregate state and create any commends/events missing, while handling multiple writers (could be done using versions). In short, I wouldn't recommend it, better be explicit with commands invoked directly or using some domain service.

    Please note that the area of DDD/CQRS/ES is very opinionated, what you see in EventFlow is just my interpretation.

    Andrey Tsvetkov
    @AndreyTsvetkov
    Hi guys! Is there any way to set up the order of ReadModels initialisation? I cannot find the source code which fires that process.
    I use in-memory readmodels, and they initialise on start, model by model: Read model 'XxxView' is interested in these aggregate events: XxxProvided, YyyCreated, ZzzProvided Loading events starting from and the next 200 for populating 'XxxView'.
    Pawel Sawicz
    @pawelsawicz
    Hey all. QQ: Would you create unit tests for aggregate state changes logic ? i.e test for SetMagicNumer
    Second question, would you assert that exception was not thrown and/or event is being emitted ?
    Rasmus Mikkelsen
    @rasmus
    @AndreyTsvetkov did you figure it out? Read model initialization is done through the IReadModelPopulator interface.
    I have been on sabbatical and trying to do as little work stuff as possible, sorry for not replying to issues.
    ckoehler-pillar
    @ckoehler-pillar
    Hey quick question, I am thinking of putting together a SAGA but this SAGA would never close...this seems wrong to me but I don't know. What does the framework think of this?
    Mario Adam
    @i-dentify

    Hey - quick question here as well... also concerning SAGAs :-D ...haven't used them yet due to a lack of understanding. But: am I right with the assumption, that I should use ISubscribeSynchronousTo<>, whenever I want to do some subsequent action triggered by an aggregate event which is - simply spoken - not aggregate-related (like e.g. sending an email, calling an external API...) - and use SAGAs, when I want to do some subsequent aggregate-related action (according to https://docs.geteventflow.net/Sagas.html)

    Regarding https://docs.geteventflow.net/Sagas.html: SAGA for creating the order, making a reservation, making a payment and ISubscribeSynchronousTo<> for sending a confirmation mail to the customer ?

    Frank Ebersoll
    @frankebersoll
    Hi Mario! You can also use subscribers for aggregate-related stuff like publishing a command or whatever. Sagas are different in that they have their own state - they‘re aggregates themselves. So you can implement stateful instances of a process with Sagas. Look for „Process Manager“ in DDD.
    Rasmus Mikkelsen
    @rasmus
    Emanuele Curati
    @ProH4Ck
    Hi, I'm implementing my first project with EventFlow! I have a question... what is the best way to validate a reference to another aggregate? I have two aggregates: A and B. B references A and the reference is mandatory. My CreateBCommand contains AId. Can I achieve this with a IsAIdValid specification called in BAggregateRoot before emit BCreatedEvent? And in this case is it correct to perform a query in a specification? I searched for a sample with this case without success... Thanks!
    Rasmus Mikkelsen
    @rasmus

    Hi @ProH4Ck .

    Seems like you are trying to have some unit of work, that ensures that a condition is true. In very large applications these locks on objects tend to be bottlenecks and could lead to slow performance.

    Personally you should try to minimize communication/requirements between aggregates as each increases the domain significantly. Better try to find some way to model the "invalid state" and handle it gracefully. Either by cancelling (another event after, not deleting the previous), mark the aggregate as unfinished/transitioning while some state isn't valid. Or even modelling the state in the domain.

    The textbook example is from banking. Instead of ensuring that there's money in the account before withdrawing any money, you simple apply an interest and lend the money.

    Remember that everything in commands, and thereby also in aggregates, should be limited to domain validation and emitting events as it might be retried (automatically done by EventFlow) if some other thread/request changes the aggregate in the mean time.

    Not a precise answer, but I hope it gives you some ideas.

    Emanuele Curati
    @ProH4Ck
    Hi @rasmus thanks for the reply! I'll implement a state field updated through a saga started by BCreatedEvent!
    Emanuele Curati
    @ProH4Ck
    I have another question: I need to call an external service to transform entities and then pass these new entities (returned from the service) to another aggregate. This is part of a saga: AAggregate -> AEvent -> Saga (started by AEvent) -> CreateBCommand -> BAggregate -> BEvent -> Saga -> [ExternalServiceCall (with BEvent data as input)] -> CreateCCommand -> CAggregate... How can I implement this? Thanks again!