Created
November 29, 2011 12:03
-
-
Save krasserm/1404574 to your computer and use it in GitHub Desktop.
Building an event-sourced web application with Akka - Part 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InvoiceService { | |
val invoicesRef = Ref(Map.empty[String, Invoice]) // naive approach | |
// ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import akka.stm._ | |
class InvoiceService { | |
val invoicesRef = Ref(Map.empty[String, Invoice]) // naive approach | |
def addInvoiceItem(invoiceId: String, invoiceItem: InvoiceItem) = atomic { | |
invoicesRef().get(invoiceId) match { | |
case None => DomainError("no invoice with id %s").fail | |
case Some(invoice) => invoice.addItem(invoiceItem).result { (events, updated) => | |
invoicesRef alter { invoices => invoices + (invoiceId -> updated) } | |
// TODO: log events | |
} | |
} | |
} | |
// ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait EventLog[E <: Event] { | |
private val eventsRef = Ref[List[E]](Nil) | |
def log(events: List[E]) { | |
eventsRef alter { current => events ::: current } | |
} | |
def store() | |
def storeAsync() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InvoiceService { | |
val invoicesRef = Ref(Map.empty[String, Invoice]) | |
val eventLog: EventLog[InvoiceEvent] = ... | |
def addInvoiceItem(invoiceId: String, invoiceItem: InvoiceItem) = atomic { | |
invoicesRef().get(invoiceId) match { | |
case None => DomainError("no invoice with id %s").fail | |
case Some(invoice) => invoice.addItem(invoiceItem).result { (events, updated) => | |
invoicesRef alter { invoices => invoices + (invoiceId -> updated) } | |
// write events to transactional event log | |
eventLog log events | |
// on commit, transfer events to persistent event log | |
deferred { eventLog.storeAsync() } | |
} | |
} | |
} | |
// ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InvoiceService { | |
val invoicesRef = Ref(Map.empty[String, Invoice]) | |
def getInvoice(invoiceId: String): Option[Invoice] = invoicesRef().get(invoiceId) | |
def getInvoices: Iterable[Invoice] = invoicesRef().values | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InvoiceService { | |
val invoicesRef = Ref(Map.empty[String, Ref[Invoice]]) | |
val eventLog: EventLog[InvoiceEvent] = ... | |
// ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InvoiceService { | |
val invoicesRef = Ref(Map.empty[String, (Ref[Invoice], EventLog[InvoiceEvent])]) | |
// ... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment