Replacing GlobalSettings.onStart and onStop
Asked Answered
U

2

6

I'm trying to migrate my GlobalSettings to playframework 2.4 but I'm having a hard time understanding what I'm supposed to do.

Currently my Global is like below, I already moved out the onRequest to the RequestHandler properly:

public class Global extends GlobalSettings {

        private BackgroundTasks backgroundTasks;



        @Override
        public void onStart(Application arg0) {
            Logger.info("Starting background tasks");
            backgroundTasks = new BackgroundTasks();
        }

        @Override
        public void onStop(Application arg0) {
            Logger.info("Stopping background tasks");
            backgroundTasks.shutdown();
            super.onStop(arg0);

            Logger.info("Saving modules data");
            for(Module m: controllers.Application.modules){
                m.saveData();
            }
        }
    }
Unjaundiced answered 5/6, 2015 at 13:35 Comment(0)
S
11

I think it should be along the line of (without package & imports)...

OnStartModule.java:

public class OnStartModule extends AbstractModule {
  @Override
  protected void configure() {    
    bind(BackgroundTasks.class).asEagerSingleton();
  }
}

BackgroundTasks.java:

@Singleton
public class BackgroundTasks {

  @Inject
  public BackgroundTasks(ApplicationLifecycle lifecycle) {
    lifecycle.addStopHook(() -> {
      Logger.info("Stopping background tasks");
      this.shutdown();

      Logger.info("Saving modules data");
      for(Module m: controllers.Application.modules){
        m.saveData();
      }
      return F.Promise.pure(null);
    });
  }
}

application.conf:

play.modules.enabled += "OnStartModule"
Scurvy answered 17/6, 2015 at 6:19 Comment(5)
This is only half a solution. ApplicationLifecycle has 'addStopHook' but no equivalent 'addStartHook'. What's the replacement for the GlobalSettings.onStart method?Gentille
@Gentille There is no addStartHook because you're supposed to use Module.configure(). In this question, we want to create a BackgroundTasks onStart, so we instantiate it with asEagerSingleton() inside configure(). ps asSingleton() is lazyScurvy
@Scurvy Sorry for delay in responding (work took me down another path for a while). My problem is that anything started as a result of 'asEagerSingleton()' can't depend on the Play application object (you get a 'java.lang.RuntimeException: There is no started application' error). I'm looking for the equivalent of 'onStart' that fires once the Play application is ready. ps not sure which 'asSingleton()' function you are speaking of.Gentille
@Scurvy I've worked out what I was doing wrong. The code I wanted to run at start up depended on some old code that was using 'import play.api.Play.current'. I've updated it so that the application object is injected into the constructor and all is working as I require. ThanksGentille
@Gentille good to hear. Sorry that I didn't managed to get back to you earlier.Scurvy
G
3

Just as an addendum to the answer. If you instantiate a class using the 'asEagerSingleton()' and it depends the play application to have been already started then you must '@Inject()' the application into your class constructor to ensure it is available.

My issue was due to my old code (pre 2.4) using the static 'import play.api.Play.current' instead of passing the play application object as a constructor argument.

I discovered the answer in the this forum post [Play 2.4] Initialise code after Application has started

Gentille answered 2/2, 2016 at 11:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.