Repository: 7mind/izumi
Pull request #1241 (2020-09-19 16:21:56)

Re-add Launchers[F] to RoleAppMain


Patch:
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/MainAppModule.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/MainAppModule.scala
index e0afade70..43cba8c71 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/MainAppModule.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/MainAppModule.scala
@@ -42,7 +42,6 @@ import izumi.reflect.Tag
   * 15. Run finalizers
   * 16. Shutdown executors
   */
-
 class MainAppModule[F[_]: TagK](
   args: ArgV,
   additionalRoles: AdditionalRoles,
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppMain.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppMain.scala
index 5997a2928..37f5ed68e 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppMain.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppMain.scala
@@ -1,8 +1,11 @@
 package izumi.distage.roles
 
 import distage._
+import cats.effect._
+import izumi.functional.bio._
 import izumi.distage.plugins.PluginConfig
 import izumi.distage.roles.RoleAppMain.{AdditionalRoles, ArgV}
+import izumi.distage.roles.launcher.AppShutdownStrategy._
 import izumi.distage.roles.launcher.{AppFailureHandler, AppShutdownStrategy, PreparedApp}
 import izumi.fundamentals.platform.cli.model.raw.RawRoleParams
 import izumi.fundamentals.platform.cli.model.schema.ParserDef
@@ -10,10 +13,15 @@ import izumi.fundamentals.platform.functional.Identity
 import izumi.fundamentals.platform.language.unused
 import izumi.reflect.Tag
 
-abstract class RoleAppMain[F[_]: TagK]()(implicit t: Tag[TagK[F]]) {
+import scala.concurrent.ExecutionContext
+
+abstract class RoleAppMain[F[_]: TagK](implicit t: Tag[TagK[F]]) {
+  protected def pluginConfig: PluginConfig
+  protected def shutdownStrategy: AppShutdownStrategy[F]
+
   def main(args: Array[String]): Unit = {
+    val argv = ArgV(args)
     try {
-      val argv = ArgV(args)
       val appModule = makeAppModule(argv)
       val overrideModule = makeAppModuleOverride(argv)
       Injector.NoProxies().produceRun(appModule.overridenBy(overrideModule)) {
@@ -22,7 +30,7 @@ abstract class RoleAppMain[F[_]: TagK]()(implicit t: Tag[TagK[F]]) {
       }
     } catch {
       case t: Throwable =>
-        createEarlyFailureHandler().onError(t)
+        createEarlyFailureHandler(argv).onError(t)
     }
   }
 
@@ -36,26 +44,34 @@ abstract class RoleAppMain[F[_]: TagK]()(implicit t: Tag[TagK[F]]) {
 
   protected def makeAppModule(args: ArgV): Module = {
     new MainAppModule[F](
-      args,
-      AdditionalRoles(requiredRoles(args)),
-      makeShutdownStrategy(),
-      makePluginConfig(),
+      args = args,
+      additionalRoles = AdditionalRoles(requiredRoles(args)),
+      shutdownStrategy = shutdownStrategy,
+      pluginConfig = pluginConfig,
     )
   }
 
-  protected def createEarlyFailureHandler(): AppFailureHandler = {
+  protected def createEarlyFailureHandler(@unused args: ArgV): AppFailureHandler = {
     AppFailureHandler.TerminatingHandler
   }
+}
+
+object RoleAppMain {
 
-  protected def makeShutdownStrategy(): AppShutdownStrategy[F]
+  abstract class LauncherF[F[_]: TagK: LiftIO](executionContext: ExecutionContext = ExecutionContext.global) extends RoleAppMain[F] {
+    override protected def shutdownStrategy: AppShutdownStrategy[F] = new CatsEffectIOShutdownStrategy(executionContext)
+  }
 
-  protected def makePluginConfig(): PluginConfig
+  abstract class LauncherBIO[F[+_, +_]: TagKK: BIOAsync] extends RoleAppMain[F[Throwable, ?]] {
+    override protected def shutdownStrategy: AppShutdownStrategy[F[Throwable, ?]] = new BIOShutdownStrategy[F]
+  }
 
-}
+  abstract class LauncherIdentity extends RoleAppMain[Identity] {
+    override protected def shutdownStrategy: AppShutdownStrategy[Identity] = new JvmExitHookLatchShutdownStrategy
+  }
 
-object RoleAppMain {
-  case class ArgV(args: Array[String])
-  case class AdditionalRoles(knownRequiredRoles: Vector[RawRoleParams])
+  final case class ArgV(args: Array[String])
+  final case class AdditionalRoles(knownRequiredRoles: Vector[RawRoleParams])
 
   object Options extends ParserDef {
     final val logLevelRootParam = arg("log-level-root", "ll", "root log level", "{trace|debug|info|warn|error|critical}")
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/launcher/PreparedApp.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/launcher/PreparedApp.scala
index f49e1c30b..2520071ec 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/launcher/PreparedApp.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/launcher/PreparedApp.scala
@@ -2,10 +2,11 @@ package izumi.distage.roles.launcher
 
 import izumi.distage.model.Locator
 import izumi.distage.model.definition.DIResource
+import izumi.distage.model.definition.DIResource.DIResourceBase
 import izumi.distage.model.effect.{DIEffect, DIEffectRunner}
 
 final case class PreparedApp[F[_]](
-  app: DIResource.DIResourceBase[F, Locator],
+  app: DIResourceBase[F, Locator],
   runner: DIEffectRunner[F],
   effect: DIEffect[F],
 ) {


Test patch:
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala
index 0e8776e0f..3822304ef 100644
--- a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala
@@ -15,14 +15,10 @@ import izumi.distage.framework.services.{IntegrationChecker, RoleAppPlanner}
 import izumi.distage.model.PlannerInput
 import izumi.distage.model.definition.{Activation, BootstrapModule, DIResource}
 import izumi.distage.plugins.PluginConfig
-import izumi.distage.roles.RoleAppMain
-import izumi.distage.roles.launcher.{AppFailureHandler, AppShutdownStrategy}
-import izumi.distage.roles.launcher.AppShutdownStrategy.ImmediateExitShutdownStrategy
 import izumi.distage.roles.test.fixtures.Fixture._
 import izumi.distage.roles.test.fixtures._
 import izumi.distage.roles.test.fixtures.roles.TestRole00
 import izumi.fundamentals.platform.functional.Identity
-import izumi.fundamentals.platform.language.SourcePackageMaterializer.thisPkg
 import izumi.fundamentals.platform.resources.ArtifactVersion
 import izumi.logstage.api.IzLogger
 import org.scalatest.wordspec.AnyWordSpec
@@ -38,18 +34,6 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
     "testservice.systemPropList.1" -> "222",
   )
 
-  class TestEntrypointBase extends RoleAppMain[IO] {
-    override protected def makeShutdownStrategy(): AppShutdownStrategy[IO] = {
-      new ImmediateExitShutdownStrategy[IO]
-    }
-
-    override protected def createEarlyFailureHandler(): AppFailureHandler = AppFailureHandler.NullHandler
-
-    override protected def makePluginConfig(): PluginConfig = PluginConfig.cached(Seq(s"$thisPkg.fixtures"))
-  }
-
-  object TestEntrypoint extends TestEntrypointBase
-
   class XXX_TestWhiteboxProbe extends PluginDef {
     val resources = new XXX_ResourceEffectsRecorder[IO]
     private var locator0: LocatorRef = null
@@ -72,7 +56,7 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
       val probe = new XXX_TestWhiteboxProbe()
 
       new TestEntrypointBase {
-        override protected def makePluginConfig(): PluginConfig = super.makePluginConfig() overridenBy probe
+        override protected def pluginConfig: PluginConfig = super.pluginConfig overridenBy probe
       }.main(
         Array(
           "-ll",
@@ -90,7 +74,7 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
       val probe = new XXX_TestWhiteboxProbe()
 
       new TestEntrypointBase() {
-        override protected def makePluginConfig(): PluginConfig = {
+        override protected def pluginConfig: PluginConfig = {
           PluginConfig.const(
             Seq(
               new ResourcesPluginBase {}.morph[PluginBase],
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/TestEntrypoint.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/TestEntrypoint.scala
new file mode 100644
index 000000000..049c5f2dd
--- /dev/null
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/TestEntrypoint.scala
@@ -0,0 +1,19 @@
+package izumi.distage.roles.test
+
+import cats.effect.IO
+import distage.plugins.PluginConfig
+import izumi.distage.roles.RoleAppMain
+import izumi.distage.roles.launcher.AppShutdownStrategy.ImmediateExitShutdownStrategy
+import izumi.fundamentals.platform.language.SourcePackageMaterializer.thisPkg
+
+object TestEntrypoint extends TestEntrypointBase
+
+class TestEntrypointBase extends RoleAppMain.LauncherF[IO] {
+  override protected def pluginConfig: PluginConfig = {
+    PluginConfig.cached(Seq(s"$thisPkg.fixtures"))
+  }
+
+  override protected def shutdownStrategy: ImmediateExitShutdownStrategy[IO] = {
+    new ImmediateExitShutdownStrategy()
+  }
+}