Yes, you are right that these events should be persisted atomically

Dne neděle 25. října 2015 0:25:02 UTC+2 Michael Omann napsal(a):
>
> You can (and should) avoid this by emitting 2 events during command 
> handling instead if one.
>
> So instead of :
>
> AddExperience(10) -> ExperienceAdded(10) -> EarnLevel(1) -> LevelEarned(1)
>
> your should derive both Events from your player's state and atomically 
> persist 2 Events using persistAll(...)
>
> AddExperience(10) -> Seq(ExperienceAdded(10), LevelEarned(1))
>
>
> It fundamental that those events are stored atomically (either both or no 
> at all), otherwise your players state could be corrupted. Imagine the first 
> event (ExperienceAdded(10)) is saved successfully while  LevelEarned(10)fails 
> to persist properly. During recovery your player would end up in an 
> inconsistent state. Those two events must be stored in a single write 
> operation.
>
>
>
>
> I also believe that using an observable member inside an actor breaks the 
> actor model. Events received in the subscribe callback (e.g. onNext()) are 
> bypassing the mailbox, adding an additional inlet to the actor. That leads 
> to many problems, shared mutable state and multithreading inside the actor 
> to name just two. I may be wrong. Maybe Patrik can comment on that.
>
>
> Mike
>
>
>
> On Tuesday, October 20, 2015 at 8:32:50 AM UTC+2, Adam Dohnal wrote:
>>
>> You understand it right. Unfortunately, your solution won't work. Suppose 
>> player has 30/100 health (current/max) and 99/100 experience and two 
>> messages are sent to him with this order:
>>
>> AddExperience(10)
>> TakeDamage(40)
>>
>> Correct behaviour is that first 10 xp is added to 109/100 ... level is 
>> earned which cause to gain full hp 100/100. Only after then TakeDamage can 
>> by applied which causes to change player's hp to 60/100.
>>
>> If you would send LevelEarned to self, it will be processed after 
>> TakeDamage message and player will die.
>>
>> I would like to process each command at the time and persist ALL its 
>> consequence. Problem is that my consequences are found asynchronously :(
>>
>> Dne pondělí 19. října 2015 12:15:33 UTC+2 Patrik Nordwall napsal(a):
>>>
>>> If I understand it correctly your question is about how to persist the 
>>> LevelEarned event which comes via the 
>>> asyncrounous player.observable.subscribe callback. Since this is an actor 
>>> you must turn that callback into a message that is sent to self and when 
>>> receiving that message you can persist it.
>>>
>>> /Patrik
>>>
>>> On Mon, Oct 12, 2015 at 3:17 PM, Adam Dohnal <dohna...@gmail.com> wrote:
>>>
>>>> Hello, 
>>>>
>>>> I am new in Akka and I am trying to develop some mini project to test 
>>>> some things (akka, rx, cqrs, es etc..)
>>>>
>>>> I think I understand the concept of cqrs/es and how it fit to akka. My 
>>>> problem is probably more theoretical than technical.
>>>>
>>>> Let's say, I have class Player, which has several Attribute[T] 
>>>> attributes ... these attributes can be for example player's current 
>>>> health, 
>>>> vitality, experience, level etc ... These attributes have dependencies ... 
>>>> for example currentHealth is defined as 10 * vitality ... if experience is 
>>>> > 100 new level is earns, which causes to add 1 vitality, which causes to 
>>>> add 10 health ... Hopefully, you get the point.
>>>>
>>>> I like the idea to implement this using reactive streams. Each 
>>>> Attribute[T] should be considered as Observable[T] and with all these 
>>>> excellent operators I can model dependencies I have described before.
>>>>
>>>> Now I am trying to model each Player as actor, which can handle 
>>>> commands (AddExperience(...), AddVitality(...) etc...) and produce events 
>>>> (ExperienceAdded(...), LevelEarned(...)) which should be event sourced.
>>>>
>>>> Problem is, that when I am handling command I directly don't know what 
>>>> events should be generated ... for example AddExperience(100) is handled 
>>>> and after some validation ExperienceAdded(100) should be persisted to 
>>>> event 
>>>> store. When it success, it should be applied to my domain, which emit 
>>>> value 
>>>> change in that attribute observable and new level can be earned ... but 
>>>> how 
>>>> can I persist that event?
>>>>
>>>> I try to write some pseudo-code
>>>>
>>>> class ExamplePersistentActor extends PersistentActor {
>>>>   val Player player = ... // domain
>>>>
>>>>   val subscription = player.observable.subscribe {
>>>> // here I get asynchronously information about that level is increased 
>>>> ... should I call persist here?
>>>> }
>>>>
>>>> val receiveCommand: Receive = {
>>>> case AddExperience(xp: Int) => {
>>>>      persist(ExperienceAdded(xp)) { event =>
>>>>   player.addExperience(xp) // should produce LevelEarned(1) event, 
>>>> which should be also persisted
>>>> }   
>>>>   }
>>>> }
>>>>
>>>> So I have reference to Player which has observable of all events that 
>>>> are produced ... but I don't how to persist them :/
>>>>
>>>> -- 
>>>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>>>> >>>>>>>>>> Check the FAQ: 
>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>> >>>>>>>>>> Search the archives: 
>>>> https://groups.google.com/group/akka-user
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Akka User List" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to akka-user+...@googlegroups.com.
>>>> To post to this group, send email to akka...@googlegroups.com.
>>>> Visit this group at http://groups.google.com/group/akka-user.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>>
>>> -- 
>>>
>>> Patrik Nordwall
>>> Typesafe <http://typesafe.com/> -  Reactive apps on the JVM
>>> Twitter: @patriknw
>>>
>>>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to