Skip to content

Instantly share code, notes, and snippets.

@kciesielski
Created September 13, 2018 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kciesielski/50ddfda53730edc78cbe9304db17d9bd to your computer and use it in GitHub Desktop.
Save kciesielski/50ddfda53730edc78cbe9304db17d9bd to your computer and use it in GitHub Desktop.
object AroundDirectives {
val timeoutResponse = HttpResponse(StatusCodes.NetworkReadTimeout, entity = "Unable to serve response within time limit.")
def aroundRequest(onRequest: HttpRequest => Try[RouteResult] => Unit)(implicit ec: ExecutionContext): Directive0 = {
extractRequestContext.flatMap { ctx =>
{
val onDone = onRequest(ctx.request)
mapInnerRoute { inner =>
withRequestTimeoutResponse(
_ => {
onDone(Success(Complete(timeoutResponse)))
timeoutResponse
}
) {
inner.andThen { resultFuture =>
resultFuture
.map {
case c @ Complete(response) =>
Complete(response.mapEntity { entity =>
if (entity.isKnownEmpty()) {
onDone(Success(c))
entity
} else {
// On an empty entity, `transformDataBytes` unsets `isKnownEmpty`.
// Call onDone right away, since there's no significant amount of
// data to send, anyway.
entity.transformDataBytes(Flow[ByteString].watchTermination() {
case (m, f) =>
f.map(_ => c).onComplete(onDone)
m
})
}
})
case other =>
onDone(Success(other))
other
}
.andThen { // skip this if you use akka.http.scaladsl.server.handleExceptions, put onDone there
case Failure(ex) =>
onDone(Failure(ex))
}
}
}
}
}
}
}
}
@wsargent
Copy link

Where does withRequestTimeoutResponse come from?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment