Skip to content

Instantly share code, notes, and snippets.

@krasserm
Created November 29, 2011 12:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krasserm/1404574 to your computer and use it in GitHub Desktop.
Save krasserm/1404574 to your computer and use it in GitHub Desktop.
Building an event-sourced web application with Akka - Part 1
class InvoiceService {
val invoicesRef = Ref(Map.empty[String, Invoice]) // naive approach
// ...
}
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
}
}
}
// ...
}
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()
}
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() }
}
}
}
// ...
}
class InvoiceService {
val invoicesRef = Ref(Map.empty[String, Invoice])
def getInvoice(invoiceId: String): Option[Invoice] = invoicesRef().get(invoiceId)
def getInvoices: Iterable[Invoice] = invoicesRef().values
}
class InvoiceService {
val invoicesRef = Ref(Map.empty[String, Ref[Invoice]])
val eventLog: EventLog[InvoiceEvent] = ...
// ...
}
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