Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use singleton controllers in play 2.5?

I'm just starting out and I dont think i understand it very well. From what I understand all controllers are created as dependencies the moment the router is created. They then live on until the router dies when the application terminates. If this is the case declaring them as singletons seem redundant.

like image 442
user25470 Avatar asked Nov 16 '16 21:11

user25470


2 Answers

If you have a controller that is instantiated by the router (ie. the default), then they are implicitly singletons, because the router exists only once. However if you inject the controller somewhere else, you'd still get a new instance unless it is marked as singleton.

Source: https://github.com/playframework/playframework/issues/4508#issuecomment-127820190

like image 182
rethab Avatar answered Nov 02 '22 03:11

rethab


To get rid of global state (which goes against the idea of a stateless design) Play introduced DI (I think around v2.4) and in v2.5 it now uses an injected router by default. Google Guice is the default DI framework packaged by Play (you can use others but Guice is the default).

Now (in general) Guice takes the view that creating new instances of a Controller is faster, and more thread safe than using a singleton - see the Guice docs for more.

If you have a need to restrict instances of a controller to only 1 then you can mark it a singleton BUT you have to make it Thread-safe since it will then be shared between threads.

I think the Activator templates could do with a bit more documentation around them to explain why they seem to generate @Singleton controllers when they do not seem to be needed since it is confusing. HomeController (in the Play-Scala seed) for example is confusingly declared @Singleton when it exhibits no case for it.

In general, it is probably best to not use @Singleton unless you have a fair understanding of immutability and thread-safety. If you think you have a use case for Singleton though just make sure you are protecting any shared state.

In a nutshell, don't use @Singleton.

like image 13
jacks Avatar answered Nov 02 '22 01:11

jacks