Skip to content

Instantly share code, notes, and snippets.

Avatar

Dmitry Komanov dkomanov

View GitHub Profile
@dkomanov
dkomanov / BlockingDao2.scala
Last active May 25, 2020
[writing-async-app-in-scala-part-3] blocking dao 2
View BlockingDao2.scala
class RobustDao(jdbcTemplate: JdbcTemplate,
blockingEc: ExecutionContext,
applicationEc: ExecutionContext) {
def get(id: String): Future[Option[RichDomainObject]] = {
Future(getBlocking(id))(blockingEc)
.map(blob => blob.map(parseJson))(applicationEc)
}
private def getBlocking(id: String): Option[String] =
jdbcTemplate.queryForObject(
@dkomanov
dkomanov / ExecutionContext.scala
Created May 25, 2020
[writing-async-app-in-scala-part-3] execution context
View ExecutionContext.scala
trait ExecutionContext {
def execute(runnable: Runnable): Unit
def reportFailure(cause: Throwable): Unit
}
@dkomanov
dkomanov / BlockingDao1.scala
Created May 25, 2020
[writing-async-app-in-scala-part-3] blocking dao 1
View BlockingDao1.scala
implicit val blockingExecutionContext =
ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(50))
class MyDao(jdbcTemplate: JdbcTemplate)(implicit ec: ExecutionContext) {
def get(id: String): Future[Option[RichDomainObject]] =
Future(getBlocking(id))
private def getBlocking(id: String): Option[RichDomainObject] =
jdbcTemplate.queryForObject(
"SELECT blob FROM table WHERE id = ?",
@dkomanov
dkomanov / FutureException3.scala
Created May 24, 2020
[writing-async-app-in-scala-part-2] trivial example
View FutureException3.scala
def rpcCall: Future[Option[String]]
def reportException(e: Throwable): Unit
def getUrlSafe: Future[Option[String]] = {
rpcCall.recover {
case e: Throwable =>
reportException(e)
None
}
}
@dkomanov
dkomanov / safeFuture.scala
Created May 23, 2020
[writing-async-app-in-scala-part-2] safeFuture implementation
View safeFuture.scala
def safeFuture[T](f: => Future[T]): Future[T] = {
try {
f
} catch {
case NonFatal(e) => Future.failed(e)
}
}
def handleFromMemcached(r: HttpRequest): Future[Option[Int]] = safeFuture {
require(r.uri != "/memcached-boom", "Memcached Boom!")
@dkomanov
dkomanov / executeLazily.scala
Created May 23, 2020
[writing-async-app-in-scala-part-2] executeLazily implementation
View executeLazily.scala
def executeLazily[Argument, Return](argument: Argument,
list: List[Argument => Future[Option[Return]]])
(implicit ec: ExecutionContext): Future[Option[Return]] = {
val promise = Promise[Option[Return]]()
val iterator = list.iterator
def completeWith(t: Try[Option[Return]]): Unit = t match {
case Success(value) =>
if (value.isDefined || !iterator.hasNext)
promise.success(value)
@dkomanov
dkomanov / RpcCaching2.scala
Created May 23, 2020
[writing-async-app-in-scala-part-2] RPC with caching 2
View RpcCaching2.scala
val handlers: List[HttpRequest => Future[Option[Int]]] = List(
handleFromMemcached,
handleFromCdn,
r => handleFromHadoop(r).map(Some.apply)
)
def handle(r: HttpRequest): Future[Int] = {
executeLazily(handlers.map(handler => () => handler(r)))
.map(_.getOrElse(throw new IllegalStateException("Hadoop should always return Some!")))
}
@dkomanov
dkomanov / RpcCaching1.scala
Created May 23, 2020
[writing-async-app-in-scala-part-2] RPC with caching
View RpcCaching1.scala
case class HttpRequest(uri: String)
def handleFromMemcached(r: HttpRequest): Future[Option[Int]] = {
require(r.uri != "/memcached-boom", "Memcached Boom!")
Future.successful(if (r.uri == "/memcached") Some(42) else None)
}
def handleFromCdn(r: HttpRequest): Future[Option[Int]] = {
require(r.uri != "/cnd-boom", "CDN Boom!")
Future.successful(if (r.uri == "/cdn") Some(42) else None)
@dkomanov
dkomanov / FutureException2.scala
Created May 23, 2020
[writing-async-app-in-scala-part-2] Unsafe Exception Propagation
View FutureException2.scala
def innocentFunction(param: AnyRef): Future[Int] = {
require(param != null)
Future.successful(42)
}
innocentFunction(null)
.map(_ => throw new IllegalStateException)
// an IllegalArgumentException will be thrown before map call
@dkomanov
dkomanov / FutureException1.scala
Created May 23, 2020
[writing-async-app-in-scala-part-2] Safe Exception Propagation
View FutureException1.scala
Future(42)
.map[Int](_ => throw new IllegalArgumentException)
.flatMap[Int](_ => throw new IllegalStateException)
// Effectively: Future.failed(new IllegalArgumentException)