When you override onStart in Global, would it block the thread running the bootstrap process?
In other words I want to make sure that Play does not start until call returns from onStart.
If this is not the case, what are good solution to do critical init process which need to happen before Play start accepting requests?
Yes, Global.onStart will block before the first request.
The GlobalSettings object in Play is a plugin. When the application is started, the routes are loaded first, then the plugins are loaded serially by calling the onStart method of each. The GlobalSettings plugin comes last in this initialization, which ensures that all other plugins are loaded first so that all of your db connections, cache, etc are available there.
The plugin initialization has to block a single thread to guarantee that:
All plugins are initialized in the exact order that is desired to prevent initialization order errors (if one plugin depends on another initializing first--for example the database plugin must always initialize before the evolutions plugin).
All plugins are initialized before the application can start processing requests. (Otherwise, you wouldn't be able to guarantee the the DB plugin was ready on the first request, for example).
Related
I have a rest endpoint which would start the scheduler of loading a XML to memory. Whenever I hit that rest endpoint, it loads the XML in memory and would return the XML after its ready (would take 10 - 15 seconds). When the same endpoint is accessed again, it would return the cached XML. Everything works fine but for now I have to manually hit the endpoint for the scheduler to start. Is there a way to hit the endpoint automatically via a simple code in startup? Or is there any other solution for this?
Normally, a component in the Nucleus is instantiated at first access, not at system start-up.
The way to have anything done at start-up in ATG is to create your component, and then to add its nucleus path to the list of initial services in the /Initial component (or from one of the many other Initial components changed off of it)
The component should be globally scoped. Because /Initial is instantiated at start-up, the services it references will also be instantiated as dependencies.
If your component is a POJO, then the no argument constructor will be invoked on component start-up, then the setX method will be called for each property with a value defined in its properties file.
If your component is extended from Generic Service, then additionally, beforeSet and afterSet methods will be called, before and after the set methods are invoked, if they exist, and finally doStartUp will be called.
This is all part of the fundamental lifecycle of components that the Nucleus manages.
This gives you a number of hooks with which to invoke your custom code.
Now, in your question, you ask how to call a REST endpoint at start-up. However, I believe what you actually want to ask is how to ensure that a particular piece of code gets executed at system start-up. A REST endpoint is how you are triggering it today, manually, from outside the Nucleus. But that does not mean that it must call a REST end point if it is to be automatically called at start up.
The easiest way to achieve what you want is
define a class that extends GenericService
override the doStartUp method
put the code you want to execute in this method, or invoke the code on another component from here
define a globally scoped component for the class
Add the component to the initialServices property of the Initial component
Restart the server and check that your code is being called at start-up. Put some debug statements in, and switch debug logging on in your layer.
Note, you may actually also want to think about whether you really need to invoke your code at system start-up. Anything in initial services adds to the start time of the server. Depending on your requirements, it may be better to do it on first access of your application service rather than at server start-up.
I have a Scala Play application and one of the controllers fires a Future which does some logging. I have a simple call back function which executes when the Future completes.
I have written a test to check whether this logging happens. The rough logic is as follows:
feature{
scenario{
Given()
// set up the call
When()
// make a FakeRequest via reverse routing - logging will done in a separate thread via a Future
Then()
Thread.sleep(50) // sleep to allow logging to finish
// check if the logging has been done
The issue is the Thread.sleep. I have added that call in to block the main testing thread in order to give enough time to elapse for the Future which does the logging in a separate thread to complete before actually doing the checks to see if the logging has been done.
My question is whether there is a better way to do this? In reality if my application is running and the logging is taking an inordinate amount of time, then the main thread which governs the application will not terminate until the Future that does the logging in a separate thread finishes. So I don't see a problem of putting in the Thread call above to simulate that. But I just want to confirm if this is correct.
For me, there is absolutely no other way than to do this. If I try to replicate how the app behaves in reality with my test, then the main thread for the test should complete and terminate even though the future for the logging is still going on; there is no call back in the test and neither should there be.
Assuming you're using ScalaTest ; you can use whenReady construct ; which periodically inspects the passed future, until it is either ready or the configured timeout has been surpassed;
see
http://www.artima.com/docs-scalatest-2.0.M5/org/scalatest/concurrent/Futures.html
http://doc.scalatest.org/2.0/index.html#org.scalatest.concurrent.ScalaFutures
I understood that GWT apps are separated into Frontend and Backend code.
In the little example that I wrote the Backend operations (XXXServiceImpl) are alwyas triggered by the Frontend (button pressed, etc.).
Question: Is there a way to run code in the Backend automatically? An example would be some initialization stuff that's not triggered by the Frontend (preferably it would be only executed once, during startup of the web app).
Calls to the server do not have to be triggered by a user. When your web app launches, it can make a call like initialize() to the backend, which will tell your server-side code to run some initialization method once.
If this initialization process is not dependent on a single client instance, you can add a check to see if the initialization has been already done and skip it in this case.
Finally, you can run a simple servlet that you can trigger manually (or using a cron-job, deferred task, etc. - depends on your platform) when you deploy your code. The drawback here is that you have to remember to do it every time a new server instance is started.
I have an EAR I deploy on JBoss. This EAR contains two main components, a set of EJBs, and a servlet. It also contains several other libraries.
In the current state of the code, there is a need to initialize some singletons so that the EJB can actually work. This init is made in the servlet, to start all data caches and initialize them. My problem is that because of this separate initialization, which can last up to 30 seconds, there is a moment during which the EJB are deployed and available, but calling them would lead to errors.
So the question is: is there a way to lock the EJB calls for the time of this initialization by the other component? Ideally, it would just queue them and execute them once the init finished, but it could also refuse them.
The only way I can think of for now would be to have a static boolean in the initializer, which would be checked in the EJB calls (their interceptor, actually). But this is far from convenient. So I'm wondering if there is another way to do it, less dirty.
Imagine I have an application written using Play 2. Imagine that application needs to grab hold of some things on startup (read a config file, grab some resources from JNDI, that kind of thing). Play handily gives us the GlobalSettings object that we can use to hook into start and stop events:
import play.api._
object Global extends GlobalSettings {
var someResource: Resource = _
override def onStart(app: Application) {
// might throw an exception if the path doesn't exist
resource = JNDI.grabThing("/some/path").asInstanceOf[Resource]
}
}
The problem is - what can we do if the initialisation fails? It seems that this is only executed when Play receives the first request for the application. If we throw an exception, that causes that request to fail, but the application keeps on running.
Ideally, what I'd like is to stop the application from starting at all if this block doesn't complete successfully. Unfortunately, calling Play.stop() doesn't actually seem to, well, stop Play. I can see that the Server trait defines def stop(), which looks promising but I can't figure out a way to get hold of the Server instance from inside my application.
Perhaps I'm looking at this the wrong way, and I'm not supposed to be able to stop Play (or even just my app) from inside my application, so suggestions for other approaches are welcome.
What's the best way to handle these errors?
It seems I'm lying. Play only continues to serve requests after an exception in onStart if you're running in dev mode (play run). If started with play start (i.e. production mode) an exception here will terminate the server, which is exactly what I wanted.
It does appear to leave the RUNNING_PID file lying around, which is irritating, but that's a separate issue...