SlideShare una empresa de Scribd logo
1 de 61
Descargar para leer sin conexión
Reactive Access to
MongoDB from Scala
Reactive Access to
MongoDB from Scala
Author: Hermann Hueck
Source code and Slides available at:
https://github.com/hermannhueck/reactive-mongo-access
http://de.slideshare.net/hermannhueck/reactive-access-to-mongodb-from-scala
Who am I?Who am I?
Hermann Hueck
Software Developer – Scala, Java 8, Akka, Play
https://www.xing.com/profile/Hermann_Hueck
AbstractAbstract
This talk explores different Scala/Java Drivers for MongoDB and different (mostly asynchronous) strategies to access the database.
The combination of Mongo drivers and programming strategies result in a variety of possible solutions each shown by a small code
sample. With the samples we can discuss the advantages and drawbacks of these stragegies.
Beginning with a discussion of …
What is asynchronous and what is reactive?
The code samples are using the following Mongo drivers for Scala and Java:
● Synchronous Casbah Scala Driver
● Asynchronous Mongo Java Driver (using Callbacks)
● Asynchronous Mongo Scala Driver (using RxScala)
● Asynchronous Recative Mongo Scala Drive
I wil combine these drivers with different reactive access strategies:
● Callbacks
● Futures
● RxScala Observables
● Akka Streams
Overview 1/4Overview 1/4
● What is the difference between asynchronous and
reactive?
● The Database Collections
● The Example Use Case
● Mongo sync driver
● Example 1: Casbah sync driver + sync data access
● Example 2: Casbah sync driver + async data
access with Future
● Example 3: Casbah sync driver + async data
access with Future and Promise
Overview 2/4Overview 2/4
● Async Mongo Java Driver
● Example 4: Async Java Driver + app code
with callbacks
● Example 5: Async Java driver + async data
access with Future and Promise +
processing the Future in app code
Overview 3/4Overview 3/4
● Async Mongo Scala driver providing MongoObservables (similar to
RX Observables)
● Example 6: Async Scala driver + app code with MongoObservable
● Example 7: Async Scala driver + conversion of MongoObservable
to rx.Observable + app code with rx.Observables
● Example 8: Async Scala driver + conversion of MongoObservable
to Publisher + RxJava app code
● Example 9: Async Scala driver + conversion of MongoObservable
to Publisher + Akka Streams app code
● Example 10: Async Scala driver + conversion of MongoObservable
to Akka Stream Source + Akka Streams app code
● Example 11: Async Scala driver + conversion of MongoObservable
to Future + processing the Future in app code
Overview 4/4Overview 4/4
● Reactive Mongo Scala Driver
● Example 12: Reactive Mongo Driver returning a Future +
processing the Future in app code
● Example 13: Reactive Mongo driver returning an Enumerator
which is converted to a Future + processing the Future in app
code
● Example 14: Reactive Mongo driver returning an Enumerator
which is converted to a Observable + RxJava application code
● Example 15: Reactive Mongo driver returning an Enumerator
which is converted to a Source + Akka Streams application
code
● Q & A
A look at synchronous codeA look at synchronous code
val simpsons: Seq[User] = blockingIO_GetDataFromDB
simpsons.foreach(println)
● Synchronous: The main thread is blocked
until IO completes. This is not acceptable for
a server.
Asynchronous CodeAsynchronous Code
val r: Runnable = new Runnable {
def run(): Unit = {
val simpsons: Seq[String] = blockingIO_GetDataFromDB
simpsons.foreach(println)
}
}
new Thread(r).start()
● Asynchronous: The main thread doesn‘t wait for
the background thread. But the background thread
is blocked until IO completes. This is the approach
of traditional application servers, which spawn one
thread per request. But this approach can be a
great waste of thread resources. It doesn‘t scale.
Reactive Code with CallbacksReactive Code with Callbacks
val callback = new SingleResultCallback[JList[String]]() {
def onResult(simpsons: JList[String], t: Throwable): Unit = {
if (t != null) {
t.printStackTrace()
} else {
jListToSeq(simpsons).foreach(println)
}
}
}
nonblockingIOWithCallbacks_GetDataFromDB(callback)
● Callbacks: They do not block on I/O, but they can
bring you to “Callback Hell“.
Reactive Code with StreamsReactive Code with Streams
val obsSimpsons: MongoObservable[String] =
nonblockingIOWithStreams_GetDataFromDB()
obsSimpsons.subscribe(new Observer[String] {
override def onNext(simpson: String): Unit = println(simpson)
override def onComplete(): Unit = println("----- DONE -----")
override def onError(t: Throwable): Unit = t.printStackTrace()
})
● Streams (here with the RxJava-like Observable
implementation of the Mongo Driver for Scala):
Streams provide the most convenient reactive
solution strategy.
What does “reactive“ mean?What does “reactive“ mean?
Reactive …
● … in our context: asynchronous + non-blocking
● … generally it is much more than that. See:
http://www.reactivemanifesto.org/
The Database CollectionsThe Database Collections
> use shop
switched to db shop
> db.users.find()
{ "_id" : "homer", "password" : "password" }
{ "_id" : "marge", "password" : "password" }
{ "_id" : "bart", "password" : "password" }
{ "_id" : "lisa", "password" : "password" }
{ "_id" : "maggie", "password" : "password" }
> db.orders.find()
{ "_id" : 1, "username" : "marge", "amount" : 71125 }
{ "_id" : 2, "username" : "marge", "amount" : 11528 }
{ "_id" : 13, "username" : "lisa", "amount" : 24440 }
{ "_id" : 14, "username" : "lisa", "amount" : 13532 }
{ "_id" : 19, "username" : "maggie", "amount" : 65818 }
The Example Use CaseThe Example Use Case
A user can generate the eCommerce statistics only from
his own orders. Therefore she first must log in to retrieve
her orders and calculate the statistics from them.
The login function queries the user by her username and
checks the password throwing an exception if the user
with that name does not exist or if the password is
incorrect.
Having logged in she queries her own orders from the
DB. Then the eCommerce statistics is computed from all
orders of this user and printed on the screen.
The Example Use Case ImplThe Example Use Case Impl
def logIn(credentials: Credentials): String = {
val optUser: Option[User] = dao.findUserByName(credentials.username)
val user: User = checkUserLoggedIn(optUser, credentials)
user.name
}
private def processOrdersOf(username: String): Result = {
Result(username, dao.findOrdersByUsername(username))
}
def eCommerceStatistics(credentials: Credentials): Unit = {
try {
val username: String = logIn(credentials)
val result: Result = processOrdersOf(username)
result.display()
}
catch {
case t: Throwable =>
Console.err.println(t.toString)
}
}
Synchronous MongoDB Java DriverSynchronous MongoDB Java Driver
● “The MongoDB Driver is the updated synchronous Java
driver that includes the legacy API as well as a new generic
MongoCollection interface that complies with a new cross-
driver CRUD specification.“ (quote from the doc)
● See:
https://mongodb.github.io/mongo-java-driver/3.3/
● SBT:
libraryDependencies += "org.mongodb" % "mongodb-driver" % "3.3.0"
// or
libraryDependencies += "org.mongodb" % "mongo-java-driver" % "3.3.0"
Imports:
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
Synchronous Casbah Driver for ScalaSynchronous Casbah Driver for Scala
● “Casbah is the legacy Scala driver for MongoDB. It provides
wrappers and extensions to the Java Driver meant to allow a
more Scala-friendly interface to MongoDB. It supports
serialization/deserialization of common Scala types (including
collections and regex), Scala collection versions of DBObject
and DBList and a fluid query DSL.“ (quote from the doc)
● See:
https://mongodb.github.io/casbah/
● SBT:
libraryDependencies += "org.mongodb" % "casbah" % "3.1.1"
Imports:
import com.mongodb.casbah.Imports._
import com.mongodb.casbah.MongoClient
Example 1: Blocking Casbah driver
+ sync db access
Example 1: Blocking Casbah driver
+ sync db access
object dao {
private def _findUserByName(name: String): Option[User] = {
usersCollection
.findOne(MongoDBObject("_id" -> name))
.map(User(_))
}
private def _findOrdersByUsername(username: String): Seq[Order] = {
ordersCollection
.find(MongoDBObject("username" -> username))
.toSeq
.map(Order(_))
}
def findUserByName(name: String): Option[User] = {
_findUserByName(name)
}
def findOrdersByUsername(username: String): Seq[Order] = {
_findOrdersByUsername(username)
}
}
Example 1: Blocking Casbah driver +
sync db access
Example 1: Blocking Casbah driver +
sync db access
● We use the synchronous Casbah driver.
● We use sync DB access code.
● A completely blocking solution.
Example 2: Blocking Casbah driver +
async db access with Future
Example 2: Blocking Casbah driver +
async db access with Future
object dao {
private def _findUserByName(name: String): Option[User] = {
// blocking access to usersCollection as before
}
private def _findOrdersByUsername(username: String): Seq[Order] = {
// blocking access to ordersCollection as before
}
def findUserByName(name: String): Future[Option[User]] = {
Future {
_findUserByName(name)
}
}
def findOrdersByUsername(username: String): Future[Seq[Order]] = {
Future {
_findOrdersByUsername(username)
}
}
}
Example 2: Blocking Casbah driver +
async db access with Future
Example 2: Blocking Casbah driver +
async db access with Future
● We still use the sync Casbah driver.
● To access and process the result of the Future
you must implement the onComplete() handler
● The app code does not block.
Example 3: Blocking Casbah driver + async
db access with Future and Promise
Example 3: Blocking Casbah driver + async
db access with Future and Promise
object dao {
private def _findOrdersByUsername(username: String): Seq[Order] = {
// blocking access to ordersCollection as before
}
def findOrdersByUsername(username: String): Future[Seq[Order]] = {
val p = Promise[Seq[Order]]
Future {
p.complete(Try {
_findOrdersByUsername(username)
})
}
p.future
}
}
Example 3: Blocking Casbah driver + async
db access with Future and Promise
Example 3: Blocking Casbah driver + async
db access with Future and Promise
● We still use the sync Casbah driver.
● To access and process the result of the Future
you must implement the onComplete() handler
● The app code does not block.
Asynchronous MongoDB Java
Driver
Asynchronous MongoDB Java
Driver
● “The new asynchronous API that can leverage either
Netty or Java 7’s AsynchronousSocketChannel for
fast and non-blocking IO.“ (quote from the doc)
● See:
https://mongodb.github.io/mongo-java-driver/3.3/driver-async/
● SBT:
libraryDependencies += "org.mongodb" % "mongodb-driver-async" % "3.3.0"
● Imports:
import com.mongodb.async.SingleResultCallback;
import com.mongodb.async.client.MongoClient;
import com.mongodb.async.client.MongoClients;
import com.mongodb.async.client.MongoCollection;
import com.mongodb.async.client.MongoDatabase;
Example 4: Async Mongo Java driver +
async db access with Callbacks
Example 4: Async Mongo Java driver +
async db access with Callbacks
object dao {
private def _findOrdersByUsername(username: String,
callback: SingleResultCallback[JList[Order]]): Unit = {
ordersCollection
.find(Filters.eq("username", username))
.map(scalaMapper2MongoMapper { doc => Order(doc) })
.into(new JArrayList[Order], callback)
}
def findOrdersByUsername(username: String,
callback: SingleResultCallback[JList[Order]]): Unit =
_findOrdersByUsername(username, callback)
}
. . .
val callback = new SingleResultCallback[JList[Order]]() {
override def onResult(orders: JList[Order], t: Throwable): Unit = {
if (t != null) {
// handle exception
} else {
// process orders
}
}
}
findOrdersByUsername("homer", callback);
Example 4: Async Mongo Java driver +
async db access with Callbacks
Example 4: Async Mongo Java driver +
async db access with Callbacks
● We use the asynchronous callback based Mongo Java
driver.
● The callback function must be passed into the invocation of
the Mongo driver.
● There is no blocking code neither in the driver nor in the
application code.
● The solution is completely reactive.
● Callback based programming may easily lead to
unmanagable code … the so called “Callback Hell“.
Example 5: Async Mongo Java driver + async
db access with Future and Promise
Example 5: Async Mongo Java driver + async
db access with Future and Promise
object dao {
private def _findOrdersByUsername(username: String,
callback: SingleResultCallback[JList[Order]]): Unit = {
ordersCollection
.find(Filters.eq("username", username))
.map(scalaMapper2MongoMapper { doc => Order(doc) })
.into(new JArrayList[Order], callback)
}
def findOrdersByUsername(username: String): Future[Seq[Order]] = {
val promise = Promise[Seq[Order]]
_findOrdersByUsername(username): new SingleResultCallback[JList[Order]]() {
override def onResult(orders: JList[Order], t: Throwable): Unit = {
if (t == null) {
promise.success(jListToSeq(orders))
} else {
promise.failure(t)
}
}
})
promise.future
}
}
Example 5: Async Mongo Java driver + async
db access with Future and Promise
Example 5: Async Mongo Java driver + async
db access with Future and Promise
● We use the asynchronous callback based Mongo driver.
● The callback function completes the Promise. Callback
code remains encapsulated inside the DAO and does
not pollute application logic. → Thus “Callback Hell“ is
avoided.
● There is no blocking code neither in the driver nor in the
application code.
● The solution is completely reactive.
MongoDB Scala Driver (async)MongoDB Scala Driver (async)
“The Scala driver is free of dependencies on any third-party
frameworks for asynchronous programming. To achieve this
the Scala API makes use of an custom implementation of
the Observer pattern which comprises three traits:
● Observable
● Observer
● Subscription
… The MongoDB Scala Driver is built upon the callback-
driven MongoDB async driver. The API mirrors the async
driver API and any methods that cause network IO return an
instance of the Observable[T] where T is the type of
response for the operation“. (quote from the doc)
MongoDB Scala Driver (async)MongoDB Scala Driver (async)
See:
https://mongodb.github.io/mongo-scala-driver/1.1
● SBT:
libraryDependencies += "org.mongodb.scala" % "mongo-scala-driver" % "1.1.1"
● Imports:
import com.mongodb.scala.MongoClient;
import com.mongodb.scala.MongoCollection;
import com.mongodb.scala.MongoDatabase;
Example 6: Mongo Scala driver + async
db access with MongoObservables
Example 6: Mongo Scala driver + async
db access with MongoObservables
object dao {
private def _findOrdersByUsername(
username: String): MongoObservable[Seq[Order]] = {
ordersCollection
.find(Filters.eq("username", username))
.map(doc => Order(doc))
.collect()
}
def findOrdersByUsername(username: String): MongoObservable[Seq[Order]] = {
_findOrdersByUsername(username)
}
}
. . .
val obsOrders: MongoObservable[Seq[Order]] = dao.findOrdersByUsername("lisa")
obsOrders.subscribe(new Observer[Seq[Order]] {
override def onNext(order: Seq[Order]): Unit = println(order)
override def onComplete(): Unit = println("----- DONE -----")
override def onError(t: Throwable): Unit = t.printStackTrace()
})
Example 6: Mongo Scala driver + async
db access with MongoObservables
Example 6: Mongo Scala driver + async
db access with MongoObservables
● We use the async Mongo Scala driver.
● This driver internally uses the Mongo async Java driver.
● The DAO function returns a MongoObservable which is a convenient
source of a stream processing pipeline.
● There is no blocking code neither in the driver nor in the application
code.
● The solution is completely reactive.
● Elegant streaming solution.
● The functionality is a bit reduced compared to the rich set of operators
in RxJava or Akka Streams.
Example 7: Mongo Scala driver + async db
access with MongoObservable + rx.Observable
Example 7: Mongo Scala driver + async db
access with MongoObservable + rx.Observable
object dao {
private def _findOrdersByUsername(
username: String): MongoObservable[Seq[Order]] = {
ordersCollection
.find(Filters.eq("username", username))
.map(doc => Order(doc))
.collect()
}
def findOrdersByUsername(username: String): rx.Observable[Seq[Order]] = {
RxScalaConversions.observableToRxObservable(_findOrdersByUsername(username))
}
}
. . .
val obsOrders: rx.Observable[Seq[Order]] = dao.findOrdersByUsername("lisa")
obsOrders.subscribe(new Observer[Seq[Order]] {
override def onNext(order: Seq[Order]): Unit = println(order)
override def onCompleted(): Unit = println("----- DONE -----")
override def onError(t: Throwable): Unit = t.printStackTrace()
})
Example 7: Mongo Scala driver + async db
access with MongoObservable + rx.Observable
Example 7: Mongo Scala driver + async db
access with MongoObservable + rx.Observable
● We use the async Mongo Scala driver.
● This driver internally uses the Mongo async driver.
● The DAO function returns an rx.Observable which is a
convenient source of a stream processing pipeline.
● There is no blocking code neither in the driver nor in the
application code.
● The solution is completely reactive.
● Elegant streaming solution.
Example 8: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + rx.Observable
Example 8: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + rx.Observable
object dao {
private def _findOrdersByUsername(
username: String): MongoObservable[Seq[Order]] = {
ordersCollection
.find(Filters.eq("username", username))
.map(doc => Order(doc))
.collect()
}
def findOrdersByUsername(username: String): Publisher[Seq[Order]] = {
RxStreamsConversions.observableToPublisher(_findOrdersByUsername(username))
}
}
. . .
val pubOrders: Publisher[Seq[Order]] = dao.findOrdersByUsername("lisa")
val obsOrders: rx.Observable[Seq[Order]] = publisherToObservable(pubOrders)
obsOrders.subscribe(new Observer[Seq[Order]] {
override def onNext(order: Seq[Order]): Unit = println(order)
override def onCompleted(): Unit = println("----- DONE -----")
override def onError(t: Throwable): Unit = t.printStackTrace()
})
Example 8: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + rx.Observable
Example 8: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + rx.Observable
● We use the Mongo Scala driver.
● The DAO function returns an org.reactivestreams.Publisher
which makes it compatible with any Reactive Streams
implementation.
See: http://www.reactive-streams.org/announce-1.0.0
● You cannot do much with a Publisher except convert it to the
native type of a compatible implementation, e.g. an RxScala
Observable.
● Having converted the Publisher to an Observable you can use
all the powerful operators of RxScala Observables.
● There is no blocking code neither in the driver nor in the
application code.
● The solution is completely reactive.
Example 9: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + Akka Streams
Example 9: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + Akka Streams
object dao {
private def _findOrdersByUsername(
username: String): MongoObservable[Seq[Order]] = {
ordersCollection
.find(Filters.eq("username", username))
.map(doc => Order(doc))
.collect()
}
def findOrdersByUsername(username: String): Publisher[Seq[Order]] = {
RxStreamsConversions.observableToPublisher(_findOrdersByUsername(username))
}
}
. . .
val pubOrders: Publisher[Seq[Order]] = dao.findOrdersByUsername("lisa")
val srcOrders: Source[Seq[Order], NotUsed] = Source.fromPublisher(pubOrders)
val f: Future[Done] = srcOrders).runForeach(order => ...)
f.onComplete(tryy => tryy match {
case Success(_) => // ...
case Failure(t) => // ...
})
Example 9: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + Akka Streams
Example 9: Mongo Scala driver + async db
access with MongoObservable + Reactive
Streams Interface + Akka Streams
● We use the Mongo Scala driver.
● The DAO function returns an org.reactivestreams.Publisher
which makes it compatible with any Reactive Streams
implementation.
See: http://www.reactive-streams.org/announce-1.0.0
● You cannot do much with a Publisher except convert it to the
native type of a compatible implementation, e.g. an Akka
Streams Source.
● Having converted the Publisher to a Source you can use all the
powerful operators available in Akka Streams.
● There is no blocking code neither in the driver nor in the
application code.
● The solution is completely reactive.
Example 10: Mongo Scala driver + async db
access with MongoObservable + Akka Streams
Example 10: Mongo Scala driver + async db
access with MongoObservable + Akka Streams
object dao {
private def _findOrdersByUsername(
username: String): MongoObservable[Seq[Order]] = {
ordersCollection
.find(Filters.eq("username", username))
.map(doc => Order(doc))
.collect()
}
def findOrdersByUsername(username: String): Source[Seq[Order], NotUsed] = {
val pubOrders: Publisher[Seq[Order]] =
RxStreamsConversions.observableToPublisher(_findOrdersByUsername(username))
Source.fromPublisher(pubOrders)
}
}
. . .
val srcOrders: Source[Seq[Order], NotUsed] = dao.findOrdersByUsername("lisa")
val f: Future[Done] = srcOrders.runForeach(order => ...)
f.onComplete(tryy => tryy match {
case Success(_) => // ...
case Failure(t) => // ...
})
Example 10: Mongo Scala driver + async db
access with MongoObservable + Akka Streams
Example 10: Mongo Scala driver + async db
access with MongoObservable + Akka Streams
● Technically identical to example no. 9
● But the DAO provides an Akka Streams
interface to the app code.
Example 11: Mongo Scala driver + async db
access with MongoObservable + Future
Example 11: Mongo Scala driver + async db
access with MongoObservable + Future
object dao {
private def _findOrdersByUsername(
username: String): MongoObservable[Order] = {
ordersCollection
.find(Filters.eq("username", username))
.map(doc => Order(doc))
}
def findOrdersByUsername(username: String): Future[Seq[Order]] = {
_findOrdersByUsername(username).toFuture
}
}
. . .
val fOrders: Future[Seq[Order]] = dao.findOrdersByUsername("lisa")
f.onComplete(tryy => tryy match {
case Success(_) => // ...
case Failure(t) => // ...
})
Example 11: Mongo Scala driver + async db
access with MongoObservable + Future
Example 11: Mongo Scala driver + async db
access with MongoObservable + Future
● We use the async Mongo Scala driver.
● This driver internally uses the Mongo async
Java driver.
● The DAO function returns a Future.
● There is no blocking code neither in the driver
nor in the application code.
● The solution is completely reactive.
Reactive Mongo DriverReactive Mongo Driver
“ReactiveMongo is a scala driver that provides
fully non-blocking and asynchronous I/O
operations.“
. . .
„ReactiveMongo is designed to avoid any kind of
blocking request. Every operation returns
immediately, freeing the running thread and
resuming execution when it is over. Accessing the
database is not a bottleneck anymore.“
(quote from the doc)
Reactive Mongo DriverReactive Mongo Driver
This driver has been implemented by the Play
Framework team and uses Akka for its
implementation.
See:
http://reactivemongo.org/
https://github.com/ReactiveMongo/ReactiveMongo
● SBT:
libraryDependencies += "org.reactivemongo" % "reactivemongo" % "0.11.14"
● Imports:
import reactivemongo.api.collections.bson.BSONCollection
import reactivemongo.api.{DefaultDB, MongoConnection, MongoDriver}
import reactivemongo.bson.BSONDocument
Example 12: Reactive Mongo driver + async db
access returning Future
Example 12: Reactive Mongo driver + async db
access returning Future
object dao {
private def _findOrdersByUsername(
username: String): Future[Seq[Order]] = {
ordersCollection
.find(BSONDocument("username" -> username))
.cursor[BSONDocument]()
.collect[Seq]()
.map { seqOptDoc =>
seqOptDoc map { doc =>
Order(doc)
}
}
}
def findOrdersByUsername(username: String): Future[Seq[Order]] = {
_findOrdersByUsername(username)
}
}
. . .
val fOrders: Future[Seq[Order]] = dao.findOrdersByUsername("lisa")
f.onComplete(tryy => tryy match {
case Success(_) => // ...
case Failure(t) => // ...
})
Example 12: Reactive Mongo driver + async db
access returning Future
Example 12: Reactive Mongo driver + async db
access returning Future
● We use the Reactive Mongo Scala driver.
● The driver returns a Future.
● The DAO function returns a Future.
● There is no blocking code neither in the driver
nor in the application code.
● The solution is completely reactive.
Example 13: Reactive Mongo driver + async db
access with Enumerator returning Future
Example 13: Reactive Mongo driver + async db
access with Enumerator returning Future
object dao {
private def _findOrdersByUsername(username: String): Enumerator[Order] = {
ordersCollection
.find(BSONDocument("username" -> username))
.cursor[BSONDocument]()
.enumerate()
.map(Order(_))
}
def findOrdersByUsername(username: String): Future[Seq[Order]] = {
toFutureSeq(_findOrdersByUsername(username))
}
}
. . .
val fOrders: Future[Seq[Order]] = dao.findOrdersByUsername("lisa")
f.onComplete(tryy => tryy match {
case Success(_) => // ...
case Failure(t) => // ...
})
Example 13: Reactive Mongo driver + async db
access with Enumerator returning Future
Example 13: Reactive Mongo driver + async db
access with Enumerator returning Future
● We use the Reactive Mongo Scala driver.
● The driver returns an Enumerator.
● The DAO function returns a Future.
● There is no blocking code neither in the driver
nor in the application code.
● The solution is completely reactive.
Example 14: Reactive Mongo driver + async db
access with Enumerator returning Observable
Example 14: Reactive Mongo driver + async db
access with Enumerator returning Observable
object dao {
private def _findOrdersByUsername(username: String): Enumerator[Order] = {
ordersCollection
.find(BSONDocument("username" -> username))
.cursor[BSONDocument]()
.enumerate()
.map(Order(_))
}
def findOrdersByUsername(username: String): Observable[Order] = {
enumeratorToObservable(_findOrdersByUsername(username))
}
}
. . .
val obsOrders: rx.Observable[Seq[Order]] = dao.findOrdersByUsername("lisa")
obsOrders.subscribe(new Observer[Seq[Order]] {
override def onNext(order: Seq[Order]): Unit = println(order)
override def onCompleted(): Unit = println("----- DONE -----")
override def onError(t: Throwable): Unit = t.printStackTrace()
})
Example 14: Reactive Mongo driver + async db
access with Enumerator returning Observable
Example 14: Reactive Mongo driver + async db
access with Enumerator returning Observable
● We use the Reactive Mongo Scala driver.
● The driver returns an Enumerator.
● The DAO function returns an Observable.
● There is no blocking code neither in the driver
nor in the application code.
● The solution is completely reactive.
Example 15: Reactive Mongo driver + async db access
with Enumerator returning Akka Streams Source
Example 15: Reactive Mongo driver + async db access
with Enumerator returning Akka Streams Source
object dao {
private def _findOrdersByUsername(username: String): Enumerator[Order] = {
ordersCollection
.find(BSONDocument("username" -> username))
.cursor[BSONDocument]()
.enumerate()
.map(Order(_))
}
def findOrdersByUsername(username: String): Source[Order, NotUsed] = {
enumeratorToSource(_findOrdersByUsername(username))
}
}
. . .
val srcOrders: Source[Order, NotUsed] = dao.findOrdersByUsername("lisa")
val f: Future[Done] = srcOrders.runForeach(order => ...)
f.onComplete(tryy => tryy match {
case Success(_) => // ...
case Failure(t) => // ...
})
Example 15: Reactive Mongo driver + async db access
with Enumerator returning Akka Streams Source
Example 15: Reactive Mongo driver + async db access
with Enumerator returning Akka Streams Source
● We use the Reactive Mongo Scala driver.
● The driver returns an Enumerator.
● The DAO function returns an Akka Streams
Source.
● There is no blocking code neither in the driver
nor in the application code.
● The solution is completely reactive.
RxScala CharacteristicsRxScala Characteristics
● Powerful set of stream operators
● Simple API
● Simple thread pool configuration with
subscribeOn() and observeOn()
● Rx ports available for many languages:
RxJava, RxJS, Rx.NET, RxScala, RxClojure,
RxSwift, RxCpp, Rx.rb, RxPy, RxGroovy,
RxJRuby, RxKotlin, RxPHP
● Rx ports available for specific platforms or
frameworks:
RxNetty, RxAndroid, RxCocoa
Akka Streams CharacteristicsAkka Streams Characteristics
● Powerful set of stream operators
● Very flexible operators to split or join streams
● API a bit more complex than RxScala API
● Powerful actor system working under the hood
● Available for Scala and Java 8
Resources – Talk / AuthorResources – Talk / Author
● Source Code and Slides on Github:
https://github.com/hermannhueck/reactive-mongo-access
● Slides on SlideShare:
http://de.slideshare.net/hermannhueck/reactive-access-to-mong
odb-from-scala
● Authors XING Profile:
https://www.xing.com/profile/Hermann_Hueck
Resources – Java Drivers for
MongoDB
Resources – Java Drivers for
MongoDB
● Overview of Java drivers for MongoDB:
https://docs.mongodb.com/ecosystem/drivers/java/
● Sync driver:
https://mongodb.github.io/mongo-java-driver/3.3/
● Async driver:
https://mongodb.github.io/mongo-java-driver/3.3/driver-async/
● How the RxJava driver and the Reactive Streams driver wrap the async driver:
https://mongodb.github.io/mongo-java-driver/3.3/driver-async/reference/observa
bles/
● RxJava driver:
https://mongodb.github.io/mongo-java-driver-rx/1.2/
● Reactive Streams driver:
https://mongodb.github.io/mongo-java-driver-reactivestreams/1.2/
● Morphia Driver:
https://mongodb.github.io/morphia/1.1/
Resources – Scala Drivers for
MongoDB
Resources – Scala Drivers for
MongoDB
● Overview of Scala drivers for MongoDB:
https://docs.mongodb.com/ecosystem/drivers/scala/
● Sync Casbah driver (a Scala wrapper for the sync Java driver):
https://mongodb.github.io/casbah/
● Async Scala driver:
https://mongodb.github.io/mongo-scala-driver/1.1/
● Reactive Mongo Scala driver:
http://reactivemongo.org/
https://github.com/ReactiveMongo/ReactiveMongo
Resources – RxJava / RxScalaResources – RxJava / RxScala
● ReactiveX:
http://reactivex.io/intro.html
● RxJava Wiki:
https://github.com/ReactiveX/RxJava/wiki
● RxScala:
https://github.com/ReactiveX/RxScala
http://reactivex.io/rxscala/scaladoc/index.html
● Nice Intro to RxJava by Dan Lev:
http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
● RxJava- Understanding observeOn() and subscribeOn() by
Thomas Nield:
http://tomstechnicalblog.blogspot.de/2016/02/rxjava-understan
ding-observeon-and.html
Resources – Reactive Streams and
Akka Streams
Resources – Reactive Streams and
Akka Streams
● Reactive Streams:
http://www.reactive-streams.org/
● Current implementations of Reactive Streams:
http://www.reactive-streams.org/announce-1.0.0
● RxJava to Reactive Streams conversion library:
https://github.com/ReactiveX/RxJavaReactiveStreams
● Akka (2.4.8) Documentation for Scala:
http://doc.akka.io/docs/akka/2.4.8/scala.html
● The Reactive Manifesto:
http://www.reactivemanifesto.org/
Thanks for your attention!
Q & A

Más contenido relacionado

La actualidad más candente

S3 整合性モデルと Hadoop/Spark の話
S3 整合性モデルと Hadoop/Spark の話S3 整合性モデルと Hadoop/Spark の話
S3 整合性モデルと Hadoop/Spark の話Noritaka Sekiyama
 
Presto, Zeppelin을 이용한 초간단 BI 구축 사례
Presto, Zeppelin을 이용한 초간단 BI 구축 사례Presto, Zeppelin을 이용한 초간단 BI 구축 사례
Presto, Zeppelin을 이용한 초간단 BI 구축 사례Hyoungjun Kim
 
High-Performance Hibernate Devoxx France 2016
High-Performance Hibernate Devoxx France 2016High-Performance Hibernate Devoxx France 2016
High-Performance Hibernate Devoxx France 2016Vlad Mihalcea
 
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催) ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催) akira6592
 
Pulsar - Distributed pub/sub platform
Pulsar - Distributed pub/sub platformPulsar - Distributed pub/sub platform
Pulsar - Distributed pub/sub platformMatteo Merli
 
さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)Takanori Sejima
 
Embulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loaderEmbulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loaderSadayuki Furuhashi
 
Evaluation of TPC-H on Spark and Spark SQL in ALOJA
Evaluation of TPC-H on Spark and Spark SQL in ALOJAEvaluation of TPC-H on Spark and Spark SQL in ALOJA
Evaluation of TPC-H on Spark and Spark SQL in ALOJADataWorks Summit
 
카프카, 산전수전 노하우
카프카, 산전수전 노하우카프카, 산전수전 노하우
카프카, 산전수전 노하우if kakao
 
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜Takahiko Ito
 
윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018
윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018
윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018devCAT Studio, NEXON
 
Play with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit TechniquePlay with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit TechniqueAngel Boy
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and NettyConstantine Slisenka
 
A simple introduction to redis
A simple introduction to redisA simple introduction to redis
A simple introduction to redisZhichao Liang
 
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정PgDay.Seoul
 
JSON:APIについてざっくり入門
JSON:APIについてざっくり入門JSON:APIについてざっくり入門
JSON:APIについてざっくり入門iPride Co., Ltd.
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)
카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)
카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)Hyunmin Lee
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDB
[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDB[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDB
[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDBNAVER D2
 

La actualidad más candente (20)

S3 整合性モデルと Hadoop/Spark の話
S3 整合性モデルと Hadoop/Spark の話S3 整合性モデルと Hadoop/Spark の話
S3 整合性モデルと Hadoop/Spark の話
 
Presto, Zeppelin을 이용한 초간단 BI 구축 사례
Presto, Zeppelin을 이용한 초간단 BI 구축 사례Presto, Zeppelin을 이용한 초간단 BI 구축 사례
Presto, Zeppelin을 이용한 초간단 BI 구축 사례
 
High-Performance Hibernate Devoxx France 2016
High-Performance Hibernate Devoxx France 2016High-Performance Hibernate Devoxx France 2016
High-Performance Hibernate Devoxx France 2016
 
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催) ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
 
Pulsar - Distributed pub/sub platform
Pulsar - Distributed pub/sub platformPulsar - Distributed pub/sub platform
Pulsar - Distributed pub/sub platform
 
さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)
 
Embulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loaderEmbulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loader
 
Evaluation of TPC-H on Spark and Spark SQL in ALOJA
Evaluation of TPC-H on Spark and Spark SQL in ALOJAEvaluation of TPC-H on Spark and Spark SQL in ALOJA
Evaluation of TPC-H on Spark and Spark SQL in ALOJA
 
카프카, 산전수전 노하우
카프카, 산전수전 노하우카프카, 산전수전 노하우
카프카, 산전수전 노하우
 
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
 
윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018
윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018
윤석주, 인하우스 웹 프레임워크 Jul8 제작기, NDC2018
 
Play with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit TechniquePlay with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit Technique
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and Netty
 
A simple introduction to redis
A simple introduction to redisA simple introduction to redis
A simple introduction to redis
 
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
 
JSON:APIについてざっくり入門
JSON:APIについてざっくり入門JSON:APIについてざっくり入門
JSON:APIについてざっくり入門
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)
카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)
카프카(kafka) 성능 테스트 환경 구축 (JMeter, ELK)
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDB
[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDB[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDB
[124]네이버에서 사용되는 여러가지 Data Platform, 그리고 MongoDB
 

Similar a Reactive Access to MongoDB from Scala

Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Hermann Hueck
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1Paras Mendiratta
 
The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88Mahmoud Samir Fayed
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in reactBOSC Tech Labs
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Google apps script database abstraction exposed version
Google apps script database abstraction   exposed versionGoogle apps script database abstraction   exposed version
Google apps script database abstraction exposed versionBruce McPherson
 
Java script basics
Java script basicsJava script basics
Java script basicsJohn Smith
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
3 things you must know to think reactive - Geecon Kraków 2015
3 things you must know to think reactive - Geecon Kraków 20153 things you must know to think reactive - Geecon Kraków 2015
3 things you must know to think reactive - Geecon Kraków 2015Manuel Bernhardt
 
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Susan Potter
 
Designing REST API automation tests in Kotlin
Designing REST API automation tests in KotlinDesigning REST API automation tests in Kotlin
Designing REST API automation tests in KotlinDmitriy Sobko
 
How To Use IO Monads in Scala?
 How To Use IO Monads in Scala? How To Use IO Monads in Scala?
How To Use IO Monads in Scala?Knoldus Inc.
 
Function as a Service in private cloud
Function as a Service in private cloud Function as a Service in private cloud
Function as a Service in private cloud lightdelay
 
Javascript sivasoft
Javascript sivasoftJavascript sivasoft
Javascript sivasoftch samaram
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays
 

Similar a Reactive Access to MongoDB from Scala (20)

Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1
 
The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Google apps script database abstraction exposed version
Google apps script database abstraction   exposed versionGoogle apps script database abstraction   exposed version
Google apps script database abstraction exposed version
 
JavaScript
JavaScriptJavaScript
JavaScript
 
Java script basics
Java script basicsJava script basics
Java script basics
 
A First Date With Scala
A First Date With ScalaA First Date With Scala
A First Date With Scala
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Angular js
Angular jsAngular js
Angular js
 
3 things you must know to think reactive - Geecon Kraków 2015
3 things you must know to think reactive - Geecon Kraków 20153 things you must know to think reactive - Geecon Kraków 2015
3 things you must know to think reactive - Geecon Kraków 2015
 
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
 
Designing REST API automation tests in Kotlin
Designing REST API automation tests in KotlinDesigning REST API automation tests in Kotlin
Designing REST API automation tests in Kotlin
 
How To Use IO Monads in Scala?
 How To Use IO Monads in Scala? How To Use IO Monads in Scala?
How To Use IO Monads in Scala?
 
Function as a Service in private cloud
Function as a Service in private cloud Function as a Service in private cloud
Function as a Service in private cloud
 
Mongo-Drupal
Mongo-DrupalMongo-Drupal
Mongo-Drupal
 
Javascript sivasoft
Javascript sivasoftJavascript sivasoft
Javascript sivasoft
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
 

Más de Hermann Hueck

What's new in Scala 2.13?
What's new in Scala 2.13?What's new in Scala 2.13?
What's new in Scala 2.13?Hermann Hueck
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in ScalaHermann Hueck
 
Future vs. Monix Task
Future vs. Monix TaskFuture vs. Monix Task
Future vs. Monix TaskHermann Hueck
 
Use Applicative where applicable!
Use Applicative where applicable!Use Applicative where applicable!
Use Applicative where applicable!Hermann Hueck
 
From Function1#apply to Kleisli
From Function1#apply to KleisliFrom Function1#apply to Kleisli
From Function1#apply to KleisliHermann Hueck
 
Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Hermann Hueck
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersHermann Hueck
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and HaskellHermann Hueck
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickHermann Hueck
 

Más de Hermann Hueck (11)

A Taste of Dotty
A Taste of DottyA Taste of Dotty
A Taste of Dotty
 
What's new in Scala 2.13?
What's new in Scala 2.13?What's new in Scala 2.13?
What's new in Scala 2.13?
 
Pragmatic sbt
Pragmatic sbtPragmatic sbt
Pragmatic sbt
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
Future vs. Monix Task
Future vs. Monix TaskFuture vs. Monix Task
Future vs. Monix Task
 
Use Applicative where applicable!
Use Applicative where applicable!Use Applicative where applicable!
Use Applicative where applicable!
 
From Function1#apply to Kleisli
From Function1#apply to KleisliFrom Function1#apply to Kleisli
From Function1#apply to Kleisli
 
Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad Transformers
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and Haskell
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with Slick
 

Último

Copilot para Microsoft 365 y Power Platform Copilot
Copilot para Microsoft 365 y Power Platform CopilotCopilot para Microsoft 365 y Power Platform Copilot
Copilot para Microsoft 365 y Power Platform CopilotEdgard Alejos
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfkalichargn70th171
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfmaor17
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 

Último (20)

Copilot para Microsoft 365 y Power Platform Copilot
Copilot para Microsoft 365 y Power Platform CopilotCopilot para Microsoft 365 y Power Platform Copilot
Copilot para Microsoft 365 y Power Platform Copilot
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdf
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 

Reactive Access to MongoDB from Scala

  • 1. Reactive Access to MongoDB from Scala Reactive Access to MongoDB from Scala Author: Hermann Hueck Source code and Slides available at: https://github.com/hermannhueck/reactive-mongo-access http://de.slideshare.net/hermannhueck/reactive-access-to-mongodb-from-scala
  • 2. Who am I?Who am I? Hermann Hueck Software Developer – Scala, Java 8, Akka, Play https://www.xing.com/profile/Hermann_Hueck
  • 3. AbstractAbstract This talk explores different Scala/Java Drivers for MongoDB and different (mostly asynchronous) strategies to access the database. The combination of Mongo drivers and programming strategies result in a variety of possible solutions each shown by a small code sample. With the samples we can discuss the advantages and drawbacks of these stragegies. Beginning with a discussion of … What is asynchronous and what is reactive? The code samples are using the following Mongo drivers for Scala and Java: ● Synchronous Casbah Scala Driver ● Asynchronous Mongo Java Driver (using Callbacks) ● Asynchronous Mongo Scala Driver (using RxScala) ● Asynchronous Recative Mongo Scala Drive I wil combine these drivers with different reactive access strategies: ● Callbacks ● Futures ● RxScala Observables ● Akka Streams
  • 4. Overview 1/4Overview 1/4 ● What is the difference between asynchronous and reactive? ● The Database Collections ● The Example Use Case ● Mongo sync driver ● Example 1: Casbah sync driver + sync data access ● Example 2: Casbah sync driver + async data access with Future ● Example 3: Casbah sync driver + async data access with Future and Promise
  • 5. Overview 2/4Overview 2/4 ● Async Mongo Java Driver ● Example 4: Async Java Driver + app code with callbacks ● Example 5: Async Java driver + async data access with Future and Promise + processing the Future in app code
  • 6. Overview 3/4Overview 3/4 ● Async Mongo Scala driver providing MongoObservables (similar to RX Observables) ● Example 6: Async Scala driver + app code with MongoObservable ● Example 7: Async Scala driver + conversion of MongoObservable to rx.Observable + app code with rx.Observables ● Example 8: Async Scala driver + conversion of MongoObservable to Publisher + RxJava app code ● Example 9: Async Scala driver + conversion of MongoObservable to Publisher + Akka Streams app code ● Example 10: Async Scala driver + conversion of MongoObservable to Akka Stream Source + Akka Streams app code ● Example 11: Async Scala driver + conversion of MongoObservable to Future + processing the Future in app code
  • 7. Overview 4/4Overview 4/4 ● Reactive Mongo Scala Driver ● Example 12: Reactive Mongo Driver returning a Future + processing the Future in app code ● Example 13: Reactive Mongo driver returning an Enumerator which is converted to a Future + processing the Future in app code ● Example 14: Reactive Mongo driver returning an Enumerator which is converted to a Observable + RxJava application code ● Example 15: Reactive Mongo driver returning an Enumerator which is converted to a Source + Akka Streams application code ● Q & A
  • 8. A look at synchronous codeA look at synchronous code val simpsons: Seq[User] = blockingIO_GetDataFromDB simpsons.foreach(println) ● Synchronous: The main thread is blocked until IO completes. This is not acceptable for a server.
  • 9. Asynchronous CodeAsynchronous Code val r: Runnable = new Runnable { def run(): Unit = { val simpsons: Seq[String] = blockingIO_GetDataFromDB simpsons.foreach(println) } } new Thread(r).start() ● Asynchronous: The main thread doesn‘t wait for the background thread. But the background thread is blocked until IO completes. This is the approach of traditional application servers, which spawn one thread per request. But this approach can be a great waste of thread resources. It doesn‘t scale.
  • 10. Reactive Code with CallbacksReactive Code with Callbacks val callback = new SingleResultCallback[JList[String]]() { def onResult(simpsons: JList[String], t: Throwable): Unit = { if (t != null) { t.printStackTrace() } else { jListToSeq(simpsons).foreach(println) } } } nonblockingIOWithCallbacks_GetDataFromDB(callback) ● Callbacks: They do not block on I/O, but they can bring you to “Callback Hell“.
  • 11. Reactive Code with StreamsReactive Code with Streams val obsSimpsons: MongoObservable[String] = nonblockingIOWithStreams_GetDataFromDB() obsSimpsons.subscribe(new Observer[String] { override def onNext(simpson: String): Unit = println(simpson) override def onComplete(): Unit = println("----- DONE -----") override def onError(t: Throwable): Unit = t.printStackTrace() }) ● Streams (here with the RxJava-like Observable implementation of the Mongo Driver for Scala): Streams provide the most convenient reactive solution strategy.
  • 12. What does “reactive“ mean?What does “reactive“ mean? Reactive … ● … in our context: asynchronous + non-blocking ● … generally it is much more than that. See: http://www.reactivemanifesto.org/
  • 13. The Database CollectionsThe Database Collections > use shop switched to db shop > db.users.find() { "_id" : "homer", "password" : "password" } { "_id" : "marge", "password" : "password" } { "_id" : "bart", "password" : "password" } { "_id" : "lisa", "password" : "password" } { "_id" : "maggie", "password" : "password" } > db.orders.find() { "_id" : 1, "username" : "marge", "amount" : 71125 } { "_id" : 2, "username" : "marge", "amount" : 11528 } { "_id" : 13, "username" : "lisa", "amount" : 24440 } { "_id" : 14, "username" : "lisa", "amount" : 13532 } { "_id" : 19, "username" : "maggie", "amount" : 65818 }
  • 14. The Example Use CaseThe Example Use Case A user can generate the eCommerce statistics only from his own orders. Therefore she first must log in to retrieve her orders and calculate the statistics from them. The login function queries the user by her username and checks the password throwing an exception if the user with that name does not exist or if the password is incorrect. Having logged in she queries her own orders from the DB. Then the eCommerce statistics is computed from all orders of this user and printed on the screen.
  • 15. The Example Use Case ImplThe Example Use Case Impl def logIn(credentials: Credentials): String = { val optUser: Option[User] = dao.findUserByName(credentials.username) val user: User = checkUserLoggedIn(optUser, credentials) user.name } private def processOrdersOf(username: String): Result = { Result(username, dao.findOrdersByUsername(username)) } def eCommerceStatistics(credentials: Credentials): Unit = { try { val username: String = logIn(credentials) val result: Result = processOrdersOf(username) result.display() } catch { case t: Throwable => Console.err.println(t.toString) } }
  • 16. Synchronous MongoDB Java DriverSynchronous MongoDB Java Driver ● “The MongoDB Driver is the updated synchronous Java driver that includes the legacy API as well as a new generic MongoCollection interface that complies with a new cross- driver CRUD specification.“ (quote from the doc) ● See: https://mongodb.github.io/mongo-java-driver/3.3/ ● SBT: libraryDependencies += "org.mongodb" % "mongodb-driver" % "3.3.0" // or libraryDependencies += "org.mongodb" % "mongo-java-driver" % "3.3.0" Imports: import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase;
  • 17. Synchronous Casbah Driver for ScalaSynchronous Casbah Driver for Scala ● “Casbah is the legacy Scala driver for MongoDB. It provides wrappers and extensions to the Java Driver meant to allow a more Scala-friendly interface to MongoDB. It supports serialization/deserialization of common Scala types (including collections and regex), Scala collection versions of DBObject and DBList and a fluid query DSL.“ (quote from the doc) ● See: https://mongodb.github.io/casbah/ ● SBT: libraryDependencies += "org.mongodb" % "casbah" % "3.1.1" Imports: import com.mongodb.casbah.Imports._ import com.mongodb.casbah.MongoClient
  • 18. Example 1: Blocking Casbah driver + sync db access Example 1: Blocking Casbah driver + sync db access object dao { private def _findUserByName(name: String): Option[User] = { usersCollection .findOne(MongoDBObject("_id" -> name)) .map(User(_)) } private def _findOrdersByUsername(username: String): Seq[Order] = { ordersCollection .find(MongoDBObject("username" -> username)) .toSeq .map(Order(_)) } def findUserByName(name: String): Option[User] = { _findUserByName(name) } def findOrdersByUsername(username: String): Seq[Order] = { _findOrdersByUsername(username) } }
  • 19. Example 1: Blocking Casbah driver + sync db access Example 1: Blocking Casbah driver + sync db access ● We use the synchronous Casbah driver. ● We use sync DB access code. ● A completely blocking solution.
  • 20. Example 2: Blocking Casbah driver + async db access with Future Example 2: Blocking Casbah driver + async db access with Future object dao { private def _findUserByName(name: String): Option[User] = { // blocking access to usersCollection as before } private def _findOrdersByUsername(username: String): Seq[Order] = { // blocking access to ordersCollection as before } def findUserByName(name: String): Future[Option[User]] = { Future { _findUserByName(name) } } def findOrdersByUsername(username: String): Future[Seq[Order]] = { Future { _findOrdersByUsername(username) } } }
  • 21. Example 2: Blocking Casbah driver + async db access with Future Example 2: Blocking Casbah driver + async db access with Future ● We still use the sync Casbah driver. ● To access and process the result of the Future you must implement the onComplete() handler ● The app code does not block.
  • 22. Example 3: Blocking Casbah driver + async db access with Future and Promise Example 3: Blocking Casbah driver + async db access with Future and Promise object dao { private def _findOrdersByUsername(username: String): Seq[Order] = { // blocking access to ordersCollection as before } def findOrdersByUsername(username: String): Future[Seq[Order]] = { val p = Promise[Seq[Order]] Future { p.complete(Try { _findOrdersByUsername(username) }) } p.future } }
  • 23. Example 3: Blocking Casbah driver + async db access with Future and Promise Example 3: Blocking Casbah driver + async db access with Future and Promise ● We still use the sync Casbah driver. ● To access and process the result of the Future you must implement the onComplete() handler ● The app code does not block.
  • 24. Asynchronous MongoDB Java Driver Asynchronous MongoDB Java Driver ● “The new asynchronous API that can leverage either Netty or Java 7’s AsynchronousSocketChannel for fast and non-blocking IO.“ (quote from the doc) ● See: https://mongodb.github.io/mongo-java-driver/3.3/driver-async/ ● SBT: libraryDependencies += "org.mongodb" % "mongodb-driver-async" % "3.3.0" ● Imports: import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoClient; import com.mongodb.async.client.MongoClients; import com.mongodb.async.client.MongoCollection; import com.mongodb.async.client.MongoDatabase;
  • 25. Example 4: Async Mongo Java driver + async db access with Callbacks Example 4: Async Mongo Java driver + async db access with Callbacks object dao { private def _findOrdersByUsername(username: String, callback: SingleResultCallback[JList[Order]]): Unit = { ordersCollection .find(Filters.eq("username", username)) .map(scalaMapper2MongoMapper { doc => Order(doc) }) .into(new JArrayList[Order], callback) } def findOrdersByUsername(username: String, callback: SingleResultCallback[JList[Order]]): Unit = _findOrdersByUsername(username, callback) } . . . val callback = new SingleResultCallback[JList[Order]]() { override def onResult(orders: JList[Order], t: Throwable): Unit = { if (t != null) { // handle exception } else { // process orders } } } findOrdersByUsername("homer", callback);
  • 26. Example 4: Async Mongo Java driver + async db access with Callbacks Example 4: Async Mongo Java driver + async db access with Callbacks ● We use the asynchronous callback based Mongo Java driver. ● The callback function must be passed into the invocation of the Mongo driver. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive. ● Callback based programming may easily lead to unmanagable code … the so called “Callback Hell“.
  • 27. Example 5: Async Mongo Java driver + async db access with Future and Promise Example 5: Async Mongo Java driver + async db access with Future and Promise object dao { private def _findOrdersByUsername(username: String, callback: SingleResultCallback[JList[Order]]): Unit = { ordersCollection .find(Filters.eq("username", username)) .map(scalaMapper2MongoMapper { doc => Order(doc) }) .into(new JArrayList[Order], callback) } def findOrdersByUsername(username: String): Future[Seq[Order]] = { val promise = Promise[Seq[Order]] _findOrdersByUsername(username): new SingleResultCallback[JList[Order]]() { override def onResult(orders: JList[Order], t: Throwable): Unit = { if (t == null) { promise.success(jListToSeq(orders)) } else { promise.failure(t) } } }) promise.future } }
  • 28. Example 5: Async Mongo Java driver + async db access with Future and Promise Example 5: Async Mongo Java driver + async db access with Future and Promise ● We use the asynchronous callback based Mongo driver. ● The callback function completes the Promise. Callback code remains encapsulated inside the DAO and does not pollute application logic. → Thus “Callback Hell“ is avoided. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 29. MongoDB Scala Driver (async)MongoDB Scala Driver (async) “The Scala driver is free of dependencies on any third-party frameworks for asynchronous programming. To achieve this the Scala API makes use of an custom implementation of the Observer pattern which comprises three traits: ● Observable ● Observer ● Subscription … The MongoDB Scala Driver is built upon the callback- driven MongoDB async driver. The API mirrors the async driver API and any methods that cause network IO return an instance of the Observable[T] where T is the type of response for the operation“. (quote from the doc)
  • 30. MongoDB Scala Driver (async)MongoDB Scala Driver (async) See: https://mongodb.github.io/mongo-scala-driver/1.1 ● SBT: libraryDependencies += "org.mongodb.scala" % "mongo-scala-driver" % "1.1.1" ● Imports: import com.mongodb.scala.MongoClient; import com.mongodb.scala.MongoCollection; import com.mongodb.scala.MongoDatabase;
  • 31. Example 6: Mongo Scala driver + async db access with MongoObservables Example 6: Mongo Scala driver + async db access with MongoObservables object dao { private def _findOrdersByUsername( username: String): MongoObservable[Seq[Order]] = { ordersCollection .find(Filters.eq("username", username)) .map(doc => Order(doc)) .collect() } def findOrdersByUsername(username: String): MongoObservable[Seq[Order]] = { _findOrdersByUsername(username) } } . . . val obsOrders: MongoObservable[Seq[Order]] = dao.findOrdersByUsername("lisa") obsOrders.subscribe(new Observer[Seq[Order]] { override def onNext(order: Seq[Order]): Unit = println(order) override def onComplete(): Unit = println("----- DONE -----") override def onError(t: Throwable): Unit = t.printStackTrace() })
  • 32. Example 6: Mongo Scala driver + async db access with MongoObservables Example 6: Mongo Scala driver + async db access with MongoObservables ● We use the async Mongo Scala driver. ● This driver internally uses the Mongo async Java driver. ● The DAO function returns a MongoObservable which is a convenient source of a stream processing pipeline. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive. ● Elegant streaming solution. ● The functionality is a bit reduced compared to the rich set of operators in RxJava or Akka Streams.
  • 33. Example 7: Mongo Scala driver + async db access with MongoObservable + rx.Observable Example 7: Mongo Scala driver + async db access with MongoObservable + rx.Observable object dao { private def _findOrdersByUsername( username: String): MongoObservable[Seq[Order]] = { ordersCollection .find(Filters.eq("username", username)) .map(doc => Order(doc)) .collect() } def findOrdersByUsername(username: String): rx.Observable[Seq[Order]] = { RxScalaConversions.observableToRxObservable(_findOrdersByUsername(username)) } } . . . val obsOrders: rx.Observable[Seq[Order]] = dao.findOrdersByUsername("lisa") obsOrders.subscribe(new Observer[Seq[Order]] { override def onNext(order: Seq[Order]): Unit = println(order) override def onCompleted(): Unit = println("----- DONE -----") override def onError(t: Throwable): Unit = t.printStackTrace() })
  • 34. Example 7: Mongo Scala driver + async db access with MongoObservable + rx.Observable Example 7: Mongo Scala driver + async db access with MongoObservable + rx.Observable ● We use the async Mongo Scala driver. ● This driver internally uses the Mongo async driver. ● The DAO function returns an rx.Observable which is a convenient source of a stream processing pipeline. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive. ● Elegant streaming solution.
  • 35. Example 8: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + rx.Observable Example 8: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + rx.Observable object dao { private def _findOrdersByUsername( username: String): MongoObservable[Seq[Order]] = { ordersCollection .find(Filters.eq("username", username)) .map(doc => Order(doc)) .collect() } def findOrdersByUsername(username: String): Publisher[Seq[Order]] = { RxStreamsConversions.observableToPublisher(_findOrdersByUsername(username)) } } . . . val pubOrders: Publisher[Seq[Order]] = dao.findOrdersByUsername("lisa") val obsOrders: rx.Observable[Seq[Order]] = publisherToObservable(pubOrders) obsOrders.subscribe(new Observer[Seq[Order]] { override def onNext(order: Seq[Order]): Unit = println(order) override def onCompleted(): Unit = println("----- DONE -----") override def onError(t: Throwable): Unit = t.printStackTrace() })
  • 36. Example 8: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + rx.Observable Example 8: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + rx.Observable ● We use the Mongo Scala driver. ● The DAO function returns an org.reactivestreams.Publisher which makes it compatible with any Reactive Streams implementation. See: http://www.reactive-streams.org/announce-1.0.0 ● You cannot do much with a Publisher except convert it to the native type of a compatible implementation, e.g. an RxScala Observable. ● Having converted the Publisher to an Observable you can use all the powerful operators of RxScala Observables. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 37. Example 9: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + Akka Streams Example 9: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + Akka Streams object dao { private def _findOrdersByUsername( username: String): MongoObservable[Seq[Order]] = { ordersCollection .find(Filters.eq("username", username)) .map(doc => Order(doc)) .collect() } def findOrdersByUsername(username: String): Publisher[Seq[Order]] = { RxStreamsConversions.observableToPublisher(_findOrdersByUsername(username)) } } . . . val pubOrders: Publisher[Seq[Order]] = dao.findOrdersByUsername("lisa") val srcOrders: Source[Seq[Order], NotUsed] = Source.fromPublisher(pubOrders) val f: Future[Done] = srcOrders).runForeach(order => ...) f.onComplete(tryy => tryy match { case Success(_) => // ... case Failure(t) => // ... })
  • 38. Example 9: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + Akka Streams Example 9: Mongo Scala driver + async db access with MongoObservable + Reactive Streams Interface + Akka Streams ● We use the Mongo Scala driver. ● The DAO function returns an org.reactivestreams.Publisher which makes it compatible with any Reactive Streams implementation. See: http://www.reactive-streams.org/announce-1.0.0 ● You cannot do much with a Publisher except convert it to the native type of a compatible implementation, e.g. an Akka Streams Source. ● Having converted the Publisher to a Source you can use all the powerful operators available in Akka Streams. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 39. Example 10: Mongo Scala driver + async db access with MongoObservable + Akka Streams Example 10: Mongo Scala driver + async db access with MongoObservable + Akka Streams object dao { private def _findOrdersByUsername( username: String): MongoObservable[Seq[Order]] = { ordersCollection .find(Filters.eq("username", username)) .map(doc => Order(doc)) .collect() } def findOrdersByUsername(username: String): Source[Seq[Order], NotUsed] = { val pubOrders: Publisher[Seq[Order]] = RxStreamsConversions.observableToPublisher(_findOrdersByUsername(username)) Source.fromPublisher(pubOrders) } } . . . val srcOrders: Source[Seq[Order], NotUsed] = dao.findOrdersByUsername("lisa") val f: Future[Done] = srcOrders.runForeach(order => ...) f.onComplete(tryy => tryy match { case Success(_) => // ... case Failure(t) => // ... })
  • 40. Example 10: Mongo Scala driver + async db access with MongoObservable + Akka Streams Example 10: Mongo Scala driver + async db access with MongoObservable + Akka Streams ● Technically identical to example no. 9 ● But the DAO provides an Akka Streams interface to the app code.
  • 41. Example 11: Mongo Scala driver + async db access with MongoObservable + Future Example 11: Mongo Scala driver + async db access with MongoObservable + Future object dao { private def _findOrdersByUsername( username: String): MongoObservable[Order] = { ordersCollection .find(Filters.eq("username", username)) .map(doc => Order(doc)) } def findOrdersByUsername(username: String): Future[Seq[Order]] = { _findOrdersByUsername(username).toFuture } } . . . val fOrders: Future[Seq[Order]] = dao.findOrdersByUsername("lisa") f.onComplete(tryy => tryy match { case Success(_) => // ... case Failure(t) => // ... })
  • 42. Example 11: Mongo Scala driver + async db access with MongoObservable + Future Example 11: Mongo Scala driver + async db access with MongoObservable + Future ● We use the async Mongo Scala driver. ● This driver internally uses the Mongo async Java driver. ● The DAO function returns a Future. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 43. Reactive Mongo DriverReactive Mongo Driver “ReactiveMongo is a scala driver that provides fully non-blocking and asynchronous I/O operations.“ . . . „ReactiveMongo is designed to avoid any kind of blocking request. Every operation returns immediately, freeing the running thread and resuming execution when it is over. Accessing the database is not a bottleneck anymore.“ (quote from the doc)
  • 44. Reactive Mongo DriverReactive Mongo Driver This driver has been implemented by the Play Framework team and uses Akka for its implementation. See: http://reactivemongo.org/ https://github.com/ReactiveMongo/ReactiveMongo ● SBT: libraryDependencies += "org.reactivemongo" % "reactivemongo" % "0.11.14" ● Imports: import reactivemongo.api.collections.bson.BSONCollection import reactivemongo.api.{DefaultDB, MongoConnection, MongoDriver} import reactivemongo.bson.BSONDocument
  • 45. Example 12: Reactive Mongo driver + async db access returning Future Example 12: Reactive Mongo driver + async db access returning Future object dao { private def _findOrdersByUsername( username: String): Future[Seq[Order]] = { ordersCollection .find(BSONDocument("username" -> username)) .cursor[BSONDocument]() .collect[Seq]() .map { seqOptDoc => seqOptDoc map { doc => Order(doc) } } } def findOrdersByUsername(username: String): Future[Seq[Order]] = { _findOrdersByUsername(username) } } . . . val fOrders: Future[Seq[Order]] = dao.findOrdersByUsername("lisa") f.onComplete(tryy => tryy match { case Success(_) => // ... case Failure(t) => // ... })
  • 46. Example 12: Reactive Mongo driver + async db access returning Future Example 12: Reactive Mongo driver + async db access returning Future ● We use the Reactive Mongo Scala driver. ● The driver returns a Future. ● The DAO function returns a Future. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 47. Example 13: Reactive Mongo driver + async db access with Enumerator returning Future Example 13: Reactive Mongo driver + async db access with Enumerator returning Future object dao { private def _findOrdersByUsername(username: String): Enumerator[Order] = { ordersCollection .find(BSONDocument("username" -> username)) .cursor[BSONDocument]() .enumerate() .map(Order(_)) } def findOrdersByUsername(username: String): Future[Seq[Order]] = { toFutureSeq(_findOrdersByUsername(username)) } } . . . val fOrders: Future[Seq[Order]] = dao.findOrdersByUsername("lisa") f.onComplete(tryy => tryy match { case Success(_) => // ... case Failure(t) => // ... })
  • 48. Example 13: Reactive Mongo driver + async db access with Enumerator returning Future Example 13: Reactive Mongo driver + async db access with Enumerator returning Future ● We use the Reactive Mongo Scala driver. ● The driver returns an Enumerator. ● The DAO function returns a Future. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 49. Example 14: Reactive Mongo driver + async db access with Enumerator returning Observable Example 14: Reactive Mongo driver + async db access with Enumerator returning Observable object dao { private def _findOrdersByUsername(username: String): Enumerator[Order] = { ordersCollection .find(BSONDocument("username" -> username)) .cursor[BSONDocument]() .enumerate() .map(Order(_)) } def findOrdersByUsername(username: String): Observable[Order] = { enumeratorToObservable(_findOrdersByUsername(username)) } } . . . val obsOrders: rx.Observable[Seq[Order]] = dao.findOrdersByUsername("lisa") obsOrders.subscribe(new Observer[Seq[Order]] { override def onNext(order: Seq[Order]): Unit = println(order) override def onCompleted(): Unit = println("----- DONE -----") override def onError(t: Throwable): Unit = t.printStackTrace() })
  • 50. Example 14: Reactive Mongo driver + async db access with Enumerator returning Observable Example 14: Reactive Mongo driver + async db access with Enumerator returning Observable ● We use the Reactive Mongo Scala driver. ● The driver returns an Enumerator. ● The DAO function returns an Observable. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 51. Example 15: Reactive Mongo driver + async db access with Enumerator returning Akka Streams Source Example 15: Reactive Mongo driver + async db access with Enumerator returning Akka Streams Source object dao { private def _findOrdersByUsername(username: String): Enumerator[Order] = { ordersCollection .find(BSONDocument("username" -> username)) .cursor[BSONDocument]() .enumerate() .map(Order(_)) } def findOrdersByUsername(username: String): Source[Order, NotUsed] = { enumeratorToSource(_findOrdersByUsername(username)) } } . . . val srcOrders: Source[Order, NotUsed] = dao.findOrdersByUsername("lisa") val f: Future[Done] = srcOrders.runForeach(order => ...) f.onComplete(tryy => tryy match { case Success(_) => // ... case Failure(t) => // ... })
  • 52. Example 15: Reactive Mongo driver + async db access with Enumerator returning Akka Streams Source Example 15: Reactive Mongo driver + async db access with Enumerator returning Akka Streams Source ● We use the Reactive Mongo Scala driver. ● The driver returns an Enumerator. ● The DAO function returns an Akka Streams Source. ● There is no blocking code neither in the driver nor in the application code. ● The solution is completely reactive.
  • 53. RxScala CharacteristicsRxScala Characteristics ● Powerful set of stream operators ● Simple API ● Simple thread pool configuration with subscribeOn() and observeOn() ● Rx ports available for many languages: RxJava, RxJS, Rx.NET, RxScala, RxClojure, RxSwift, RxCpp, Rx.rb, RxPy, RxGroovy, RxJRuby, RxKotlin, RxPHP ● Rx ports available for specific platforms or frameworks: RxNetty, RxAndroid, RxCocoa
  • 54. Akka Streams CharacteristicsAkka Streams Characteristics ● Powerful set of stream operators ● Very flexible operators to split or join streams ● API a bit more complex than RxScala API ● Powerful actor system working under the hood ● Available for Scala and Java 8
  • 55. Resources – Talk / AuthorResources – Talk / Author ● Source Code and Slides on Github: https://github.com/hermannhueck/reactive-mongo-access ● Slides on SlideShare: http://de.slideshare.net/hermannhueck/reactive-access-to-mong odb-from-scala ● Authors XING Profile: https://www.xing.com/profile/Hermann_Hueck
  • 56. Resources – Java Drivers for MongoDB Resources – Java Drivers for MongoDB ● Overview of Java drivers for MongoDB: https://docs.mongodb.com/ecosystem/drivers/java/ ● Sync driver: https://mongodb.github.io/mongo-java-driver/3.3/ ● Async driver: https://mongodb.github.io/mongo-java-driver/3.3/driver-async/ ● How the RxJava driver and the Reactive Streams driver wrap the async driver: https://mongodb.github.io/mongo-java-driver/3.3/driver-async/reference/observa bles/ ● RxJava driver: https://mongodb.github.io/mongo-java-driver-rx/1.2/ ● Reactive Streams driver: https://mongodb.github.io/mongo-java-driver-reactivestreams/1.2/ ● Morphia Driver: https://mongodb.github.io/morphia/1.1/
  • 57. Resources – Scala Drivers for MongoDB Resources – Scala Drivers for MongoDB ● Overview of Scala drivers for MongoDB: https://docs.mongodb.com/ecosystem/drivers/scala/ ● Sync Casbah driver (a Scala wrapper for the sync Java driver): https://mongodb.github.io/casbah/ ● Async Scala driver: https://mongodb.github.io/mongo-scala-driver/1.1/ ● Reactive Mongo Scala driver: http://reactivemongo.org/ https://github.com/ReactiveMongo/ReactiveMongo
  • 58. Resources – RxJava / RxScalaResources – RxJava / RxScala ● ReactiveX: http://reactivex.io/intro.html ● RxJava Wiki: https://github.com/ReactiveX/RxJava/wiki ● RxScala: https://github.com/ReactiveX/RxScala http://reactivex.io/rxscala/scaladoc/index.html ● Nice Intro to RxJava by Dan Lev: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ ● RxJava- Understanding observeOn() and subscribeOn() by Thomas Nield: http://tomstechnicalblog.blogspot.de/2016/02/rxjava-understan ding-observeon-and.html
  • 59. Resources – Reactive Streams and Akka Streams Resources – Reactive Streams and Akka Streams ● Reactive Streams: http://www.reactive-streams.org/ ● Current implementations of Reactive Streams: http://www.reactive-streams.org/announce-1.0.0 ● RxJava to Reactive Streams conversion library: https://github.com/ReactiveX/RxJavaReactiveStreams ● Akka (2.4.8) Documentation for Scala: http://doc.akka.io/docs/akka/2.4.8/scala.html ● The Reactive Manifesto: http://www.reactivemanifesto.org/
  • 60. Thanks for your attention!
  • 61. Q & A