Andrew, 

Many thanks for your time and detailed response. This is very helpful as it 
gives me the direction I want to proceed. 

I'm aware that with CQRS I get eventual consistency. The scenario and 
requirements are artificial to provide a working use case. My main goal is 
see how far can I take this idea in terms of scale and performance. I'll 
report back with  findings and numbers once I've a working version. 

Thanks again ! 

-Soumya
 

On Tuesday, December 30, 2014 6:37:41 AM UTC-5, Andrew Easter wrote:
>
> Firstly, your proposal is to use event sourcing and CQRS. Using 
> akka-persistence to implement this approach necessitates you being 
> comfortable with eventual consistency - i.e. there's no guarantee that your 
> views (the Q in CQRS) will be up to date with the domain model (stored as 
> events with current state represented within your persistent actor).
>
> In a majority of cases, eventual consistency is completely tolerable, 
> despite one's initial thought to be that the write model and the view model 
> must be completely in sync. There are definitely some ways you can tolerate 
> eventual consistency given your requirements.
>
> For the aggregate representing the flash sale, you can view an incoming 
> command as an attempt to reserve an item for a specified user/cart. As your 
> actor will only process one command at a time, you can be sure that you 
> will not commit to sell beyond the quantity available. So, I think 
> modelling each flash sale as a single persistent actor can work for you, 
> and, from my understanding, there's reason to be confident that this 
> wouldn't be a critical bottleneck given the number of potential users you 
> talk about.
>
> You have a couple of options with regard to what you do about notifying a 
> user as to whether they've successfully reserved an item. You can either 
> return a message back from your persistent actor to acknowledge 
> success/failure, and/or you can implement a true CQRS approach where some 
> view model is updated (in response to a generated event - e.g. ItemReserved 
> or ItemNotReserved) that the query side can look up to determine 
> success/failure. You'll probably need to give some thought to the idea that 
> an item reservation is time limited, i.e. has an expiry, such that it can 
> be released back if the user doesn't actually complete checkout within the 
> allotted time.
>
> With this in mind, I'd be inclined to think about introducing a specific 
> domain concept to represent an item reservation, storing those details 
> within the actor state, rather than just having a single quantity that's 
> decremented. Then, on the view side, your reservations view model can be 
> queried to see whether an item was successfully reserved, who it was 
> reserved for, and include details of when the reservation will expire. You 
> could correlate a reservation back with an originating command by using 
> some kind of unique id that was passed in with the command. I'd also advise 
> keeping a separate view model as a high level overview of the overall flash 
> sale, including quantity of the item remaining - this view would listen to 
> all events generated via the flash sale actor, e.g. 
> FlashSaleCreated(quantity: Int), ItemReserved, ItemsSoldOut etc. You could 
> run a periodic job within the persistent actor to clear up expired 
> reservations = i.e. if a reservation has expired, send a 
> ExpireItemReservation command to self, and allow it to be processed, 
> leading to the quantity being incremented and an ItemReservationExpired 
> event. Something along those lines, anyway!
>
> As far as the UI showing a "Sold Out" button, this is where eventual 
> consistency is perfectly tolerable for you (in my opinion). You obviously 
> wouldn't tie the true availability of an item to the state of the UI 
> button. It doesn't really matter if, for some users, the button appears 
> enabled but their reservation still ultimately fails once they click it. 
> You just have to ensure you message appropriately to explain that, 
> unfortunately, the item was sold out after all.
>
> If you haven't already looked into the awesome Akka ClusterSharding 
> extension, then I recommend you do so. You'll see how you could scale out 
> many concurrent flash sales across a whole cluster.
>
> One problem you're maybe likely to run into is the current state of the 
> PersistentView in akka-persistence. It doesn't currently support projecting 
> a view across multiple persistent actors of the same 'type', thus making it 
> more difficult to achieve a true CQRS implementation. The issue here is 
> that you'd typically want, in your case, a view to project data from 
> multiple flash sales. There are plans to introduce this feature in 2015. 
> You just need to be aware that, currently, you'd have to find alternative 
> ways to achieve this functionality until it's available within the core of 
> akka-persistence.
>
> Hope some of this made some sense to you?!
>
>
>
> On Tuesday, 30 December 2014 02:20:05 UTC, Soumya Simanta wrote:
>>
>> I'm trying to build a prototype using DDD/CQRS and do some bench marking.
>>
>> Here are the details of the scenario (flash sale capability) I want to 
>> model. 
>>
>> 1. The primary constraint is that there are "limited" quantity of each 
>> item (only 1000)  
>> 2. Invitation for the flash sale is sent to  100K users 
>> 3. 20K invited users log in at the "same" time to buy the item at a given 
>> time say 10 AM. 
>> 4. Only 1000 of these 20K users should be able to buy the item. 
>> 5. To keep it simple I want to start with only one item. 
>> 6. All this can happen in the* order of few seconds.* 
>>
>>
>> I'm creating an AggregateRoot (an PersistentActor) called 
>> ItemInventoryAggregate. This Actor *enforces* the check that *an item 
>> can only be added to cart as long as there is available quantities left*. 
>> My concern is that this check is there in only a *single* actor thereby 
>> making it a bottleneck (?). I want to verify if I'm on the correct track. 
>>  Will this approach scale or do I need to rethink my design? 
>>
>> One the view side I want to make sure that as soon as item is unavailable 
>> I want to "show a soldout button" on the UI. As you can see all 1000 items 
>> can be sold out in 1-2 seconds. Will the view side be consistent (i.e., it 
>> will be see all items are sold out) in this window of time ?   
>>
>>
>>
>> object ItemInventoryAggregate {
>>
>>
>>   //state
>>   case class ItemQuantity(quantity: Int = 0) extends State
>>
>>   //commands
>>   case class AddToInventory(quantity: Int) extends Command
>>
>>   case object AddItemToCart extends Command
>>
>>   case object RemoveItemFromCart extends Command
>>
>>   //events
>>   case class ItemsAddedToInventory(quantity: Int) extends Event
>>
>>   case object ItemAddedToCart extends Event
>>
>>   case object ItemRemovedFromCart extends Event
>>
>>   def props(id: String, name: String): Props = 
>> Props[ItemInventoryAggregate](new ItemInventoryAggregate(id, name))
>>
>> }
>>
>>
>> ...
>>   override def updateState(evt: AggregateRoot.Event): Unit = evt match {
>>     case ItemsAddedToInventory(newItemsQty: Int) =>
>>       if (newItemsQty > 0) {
>>         state = ItemQuantity(newItemsQty)
>>         context.become(created)
>>         state match {
>>           case s: ItemQuantity => state = s.copy(quantity = s.quantity + 
>> newItemsQty)
>>           case _ => //nothing
>>         }
>>       }
>>     case ItemAddedToCart =>
>>       state match {
>>         case s: ItemQuantity => if (s.quantity > 0) state = 
>> s.copy(quantity = s.quantity - 1)
>>         case _ => //nothing
>>       }
>>     case ItemRemovedFromCart =>
>>       state match {
>>         case s: ItemQuantity => state = s.copy(quantity = s.quantity + 1)
>>         case _ => //nothing
>>       }
>>   }
>> ...
>>
>>
>> I'm planning to use akka, spray/akka-http, akka-persistence, play2, 
>> cassandra-journal for implementing this. 
>> My understanding is that each of these components is quite performant and 
>> can be used to achieve the requirements I've outlined above. 
>>
>>
>>
>>

-- 
>>>>>>>>>>      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 [email protected].
To post to this group, send email to [email protected].
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