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