akka/akka-core

Ddata GMap

Open

#27,716 opened on Sep 16, 2019

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Scala (3,547 forks)batch import
1 - triagedhelp wantedt:distributed-data

Repository metrics

Stars
 (13,277 stars)
PR merge metrics
 (Avg merge 8d 19h) (10 merged PRs in 30d)

Description

A Grow-only Map would be particularly useful for implementing products CRDTs, eg, if you had a case class (or like structure) that holds multiple CRDTs (which could themselves be products) that together represent one logical entity, and you want to be able to update them all atomically. It can be implemented currently with an ORMap, though ORMaps have the overhead of all the vectors and tags etc that isn't necessary for the product use case. Plus, for the product use case, you would likely want delta CRDT support on the values, and ORMap doesn't currently support that.

A feature that would pair nicely with this is a marshaller/unmarshaller abstraction, so you could work with a case class directly, rather than having to turn it to/from a GMap manually.

Here's an example such CRDT:

case class ShoppingCart(
  items: PNCounterMap[String],
  checkedOut: Flag,
  deliveryDetails: LWWRegister[DeliveryDetails]
) {

  def withDeliveryDetails(details: DeliveryDetails) = 
    copy(deliveryDetails = deliveryDetails.withValueOf(details))

  def checkout = copy(checkedOut = checkedOut.switchOn)

  def checkout(deliveryDetails: DeliveryDetails) = 
    copy(
      checkedOut = checkedOut.switchOn,
      deliveryDetails = deliveryDetails.withValueOf(details)
    )

  def addItems(productId: String, count: Int) = 
    copy(items = items.incrementBy(productId, count))

  def removeItems(productId: String, count: Int) =
    copy(items = items.decementBy(productId, count))

  def removeAllItems(productId: String) = 
    copy(items = items.remove(productId))
}

Contributor guide