Skip to content

Commit

Permalink
Merge pull request #5147 from dotta/wip/application-lifecycle-api-exi…
Browse files Browse the repository at this point in the history
…stentials

ApplicationLifecycle stop hook can take an existential type
  • Loading branch information
jroper committed Oct 8, 2015
2 parents 5d68300 + b772699 commit a2a49f3
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 13 deletions.
Expand Up @@ -20,7 +20,7 @@ public DelegateApplicationLifecycle(play.api.inject.ApplicationLifecycle delegat
}

@Override
public void addStopHook(final Callable<F.Promise<Void>> hook) {
public void addStopHook(final Callable<F.Promise<?>> hook) {
delegate.addStopHook(hook);
}
}
Expand Up @@ -225,7 +225,7 @@ case class FakeApplication(
override def plugins: Seq[Plugin.Deprecated] = app.plugins
override def requestHandler: HttpRequestHandler = app.requestHandler
override def errorHandler: HttpErrorHandler = app.errorHandler
override def stop(): Future[Unit] = app.stop()
override def stop(): Future[_] = app.stop()
override def injector: Injector = app.injector
}

Expand Down
Expand Up @@ -25,5 +25,5 @@ public interface ApplicationLifecycle {
* The stop hook should redeem the returned future when it is finished shutting down. It is acceptable to stop
* immediately and return a successful future.
*/
public void addStopHook(Callable<F.Promise<Void>> hook);
public void addStopHook(Callable<F.Promise<?>> hook);
}
Expand Up @@ -204,7 +204,7 @@ trait Application {
/**
* Stop the application. The returned future will be redeemed when all stop hooks have been run.
*/
def stop(): Future[Unit]
def stop(): Future[_]

/**
* Get the injector for this application.
Expand Down
Expand Up @@ -54,18 +54,16 @@ trait ApplicationLifecycle {
* The stop hook should redeem the returned future when it is finished shutting down. It is acceptable to stop
* immediately and return a successful future.
*/
def addStopHook(hook: () => Future[Unit]): Unit
def addStopHook(hook: () => Future[_]): Unit

/**
* Add a stop hook to be called when the application stops.
*
* The stop hook should redeem the returned future when it is finished shutting down. It is acceptable to stop
* immediately and return a successful future.
*/
def addStopHook(hook: Callable[F.Promise[Void]]): Unit = {
import play.api.libs.iteratee.Execution.Implicits.trampoline
addStopHook(() => hook.call().wrapped().map(_ => ()))
}
def addStopHook(hook: Callable[F.Promise[_]]): Unit =
addStopHook(() => hook.call().wrapped())
}

/**
Expand All @@ -74,9 +72,9 @@ trait ApplicationLifecycle {
@Singleton
class DefaultApplicationLifecycle extends ApplicationLifecycle {
private val mutex = new Object()
@volatile private var hooks = List.empty[() => Future[Unit]]
@volatile private var hooks = List.empty[() => Future[_]]

def addStopHook(hook: () => Future[Unit]) = mutex.synchronized {
def addStopHook(hook: () => Future[_]) = mutex.synchronized {
hooks = hook :: hooks
}

Expand All @@ -85,12 +83,12 @@ class DefaultApplicationLifecycle extends ApplicationLifecycle {
*
* @return A future that will be redeemed once all hooks have executed.
*/
def stop(): Future[Unit] = {
def stop(): Future[_] = {

// Do we care if one hook executes on another hooks redeeming thread? Hopefully not.
import play.api.libs.iteratee.Execution.Implicits.trampoline

hooks.foldLeft(Future.successful(())) { (future, hook) =>
hooks.foldLeft(Future.successful[Any](())) { (future, hook) =>
future.flatMap { _ =>
hook().recover {
case e => Logger.error("Error executing stop hook", e)
Expand Down

0 comments on commit a2a49f3

Please sign in to comment.