Skip to content

Instantly share code, notes, and snippets.

@pierangeloc
Created July 27, 2020 14:49
Show Gist options
  • Save pierangeloc/ec72d68dc9700d36dd61202c96cb1462 to your computer and use it in GitHub Desktop.
Save pierangeloc/ec72d68dc9700d36dd61202c96cb1462 to your computer and use it in GitHub Desktop.
A small app to test how akka default timeout vs `withRequestTimeout` works
package api
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse, StatusCodes}
import akka.stream.ActorMaterializer
import scala.concurrent.Future
import scala.concurrent.duration._
import akka.http.scaladsl.server.Directives._
import api.StatusRoute.{complete, get, path}
import com.typesafe.scalalogging.LazyLogging
import scala.io.StdIn
import scala.util.{Failure, Success}
object Serverino extends App with LazyLogging {
implicit val actorSystem = ActorSystem()
implicit val mat = ActorMaterializer()
import actorSystem.dispatcher
def lasting[A](d: FiniteDuration)(a: => A): Future[A] =
akka.pattern.after(d, actorSystem.scheduler)(
Future.successful(a)
)
def showRequest(request: HttpRequest): String =
s"""HttpRequest(method: ${request.method}, ${request.uri}""".stripMargin
val timeoutResponse = HttpResponse(
StatusCodes.EnhanceYourCalm,
entity = "Unable to serve response within time limit, please enhance your calm.")
val route = get {
path("users") {
parameters('userId.as[String], 'secs.as[Long]) { (userId, secs) =>
onComplete(lasting(secs.seconds)(s"I received a GET for user $userId")) {
case Success(a) => complete(a)
case Failure(a) => complete("ERROR!")
}
}
} ~
path("users-with-timeout") {
withRequestTimeout(5.second, req => {
logger.error(s"Request ${showRequest(req)} timed out")
timeoutResponse
}) {
parameters('userId.as[String], 'secs.as[Long]) { (userId, secs) =>
onComplete(lasting(secs.seconds)(s"I received a GET for user $userId")) {
case Success(a) => complete(a)
case Failure(a) => complete("ERROR!")
}
}
}
} ~
path("hello") {
complete("HELLO THERE!")
}
}
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine() // let it run until user presses return
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => actorSystem.terminate()) // and shutdown when done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment