I have an issue, with playframework just after startup.
I have this simple controller:
@Singleton
class BomberManController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {
def index() = Action { implicit request: Request[AnyContent] =>
Ok("test")
}
}
On first call, on prod env, the request take 400ms, at the second request it take 2ms.
I don't understand why and how optimise that. On my project the request must take less than 300ms.
Did you have any idea?
PlayVersion: 2.6
One option is to create a dummy Request and apply it directly in the constructor of the controller via index.apply(request). Consider the definition and the call point of warmUp method bellow:
@Singleton
class BomberManController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {
warmUp()
def index() = Action { implicit request: Request[AnyContent] =>
Ok("test")
}
private def warmUp() = {
val requestFactory = new DefaultRequestFactory(HttpConfiguration())
val request =
requestFactory.createRequest(
RemoteConnection("127.0.0.1", false, None),
"GET",
RequestTarget("/", "/", Map.empty),
"HTTP/1.1",
Headers(),
TypedMap.empty,
AnyContentAsEmpty
)
index.apply(request)
}
}
In production BomberManController is instantiated on application start and thus warmUp will be called which in turn hits index endpoint.
To test this production behaviour locally, set play.http.secret.key in application.conf and start application with
sbt clean runProd
If you do not wish to pollute your controllers with warmUp utility methods, you could separate this concern into an utility singleton, say WarmUpUtility, and make use of eager singleton binding. For example:
@Singleton
class WarmUpUtility @Inject()(bomberManController: BomberManController)() {
warmUp()
private def warmUp() = {
val requestFactory = new DefaultRequestFactory(HttpConfiguration())
val request =
requestFactory.createRequest(
RemoteConnection("127.0.0.1", false, None),
"GET",
RequestTarget("/", "/", Map.empty),
"HTTP/1.1",
Headers(),
TypedMap.empty,
AnyContentAsEmpty
)
bomberManController.index.apply(request)
}
}
// Module should be in the root package
class Module extends AbstractModule {
override def configure() = {
bind(classOf[WarmUpUtility]).asEagerSingleton()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With