現在、自動検出サービスでクラスタ化されたplay + akkaの実装を実装しようとしています。しかし、私は遊びに含まれているGuice DIローダーの問題に遭遇しているようです。そのドキュメントの状態からの抜粋:再生フレームワークを使用したAkkaクラスタの設定
https://www.playframework.com/documentation/2.5.x/ScalaAkka#Integrating-with-Akka
我々はライフサイクルフックなど、そのような正しいクラスローダなどのすべてを設定して、あなたは、俳優のシステムに組み込まれて使用をお勧めしますが、あなたを止めるものは何もありませんあなた自身の俳優システムを使用することから。
Playがシャットダウンしたときにアクターシステムをシャットダウンするためのストップフックを登録してください。 プレイ環境から正しいクラスローダーを渡す必要があります。そうしないと、Akkaはあなたのアプリケーションを見つけることができませんクラス
play.akka.configを使用してPlayの読み込み場所を変更するか、デフォルトのakka設定からakka設定を読み込まないようにしてくださいシステムは同じリモートポートにバインドしようとします
私はd私はそれがちょうど今、しかし、これを回避するために、私自身のGuiceApplicationBuilderを作成しようとした
class BuiltinModule extends Module {
def bindings(env: Environment, configuration: Configuration): Seq[Binding[_]] =
{
def dynamicBindings(factories: ((Environment, Configuration) => Seq[Binding[_]])*) = {
factories.flatMap(_(env, configuration))
}
Seq(
bind[Environment] to env,
bind[ConfigurationProvider].to(new ConfigurationProvider(configuration)),
bind[Configuration].toProvider[ConfigurationProvider],
bind[HttpConfiguration].toProvider[HttpConfiguration.HttpConfigurationProvider],
// Application lifecycle, bound both to the interface, and its implementation, so that Application can access it
// to shut it down.
bind[DefaultApplicationLifecycle].toSelf,
bind[ApplicationLifecycle].to(bind[DefaultApplicationLifecycle]),
bind[Application].to[DefaultApplication],
bind[play.Application].to[play.DefaultApplication],
bind[Router].toProvider[RoutesProvider],
bind[play.routing.Router].to[JavaRouterAdapter],
bind[ActorSystem].toProvider[ActorSystemProvider],
bind[Materializer].toProvider[MaterializerProvider],
bind[ExecutionContextExecutor].toProvider[ExecutionContextProvider],
bind[ExecutionContext].to[ExecutionContextExecutor],
bind[Executor].to[ExecutionContextExecutor],
bind[HttpExecutionContext].toSelf,
bind[CryptoConfig].toProvider[CryptoConfigParser],
bind[CookieSigner].toProvider[CookieSignerProvider],
bind[CSRFTokenSigner].toProvider[CSRFTokenSignerProvider],
bind[AESCrypter].toProvider[AESCrypterProvider],
bind[play.api.libs.Crypto].toSelf,
bind[TemporaryFileCreator].to[DefaultTemporaryFileCreator]
) ++ dynamicBindings(
HttpErrorHandler.bindingsFromConfiguration,
HttpFilters.bindingsFromConfiguration,
HttpRequestHandler.bindingsFromConfiguration,
ActionCreator.bindingsFromConfiguration
)
}
}
:彼らはしかし、私はプレーを回避することができないようお勧めします1つの上記の構成はまだそれがBuiltInModuleから内部ActorSystemProviderのバインディング代わりにBuiltInModuleから重複バインディング例外を移動します。
ここで私がしようとしているものです:
AkkaConfigModule:
package module.akka
import com.google.inject.{AbstractModule, Inject, Provider, Singleton}
import com.typesafe.config.Config
import module.akka.AkkaConfigModule.AkkaConfigProvider
import net.codingwell.scalaguice.ScalaModule
import play.api.Application
/**
* Created by dmcquill on 8/15/16.
*/
object AkkaConfigModule {
@Singleton
class AkkaConfigProvider @Inject() (application: Application) extends Provider[Config] {
override def get() = {
val classLoader = application.classloader
NodeConfigurator.loadConfig(classLoader)
}
}
}
/**
* Binds the application configuration to the [[Config]] interface.
*
* The config is bound as an eager singleton so that errors in the config are detected
* as early as possible.
*/
class AkkaConfigModule extends AbstractModule with ScalaModule {
override def configure() {
bind[Config].toProvider[AkkaConfigProvider].asEagerSingleton()
}
}
ActorSystemModule:
package module.akka
import actor.cluster.ClusterMonitor
import akka.actor.ActorSystem
import com.google.inject._
import com.typesafe.config.Config
import net.codingwell.scalaguice.ScalaModule
import play.api.inject.ApplicationLifecycle
import scala.collection.JavaConversions._
/**
* Created by dmcquill on 7/27/16.
*/
object ActorSystemModule {
@Singleton
class ActorSystemProvider @Inject() (val lifecycle: ApplicationLifecycle, val config: Config, val injector: Injector) extends Provider[ActorSystem] {
override def get() = {
val system = ActorSystem(config.getString(NodeConfigurator.CLUSTER_NAME_PROP), config.getConfig("fitnessApp"))
// add the GuiceAkkaExtension to the system, and initialize it with the Guice injector
GuiceAkkaExtension(system).initialize(injector)
system.log.info("Configured seed nodes: " + config.getStringList("fitnessApp.akka.cluster.seed-nodes").mkString(", "))
system.actorOf(GuiceAkkaExtension(system).props(ClusterMonitor.name))
lifecycle.addStopHook {() =>
system.terminate()
}
system
}
}
}
/**
* A module providing an Akka ActorSystem.
*/
class ActorSystemModule extends AbstractModule with ScalaModule {
import module.akka.ActorSystemModule.ActorSystemProvider
override def configure() {
bind[ActorSystem].toProvider[ActorSystemProvider].asEagerSingleton()
}
}
アプリケーションローダー:
class CustomApplicationLoader extends GuiceApplicationLoader {
override def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {
initialBuilder
.overrides(overrides(context): _*)
.bindings(new AkkaConfigModule, new ActorSystemModule)
}
}
私は旧姓主なものを達成するためには、AkkaクラスターのシードノードをプログラムでロードできるようにActorSystemを構成します。
上記のアプローチが適切なアプローチですか、これを達成する良い方法がありますか?これが正しいアプローチであれば、私は基本的に遊び/ guiceのDI設定について理解していませんか?
更新
このアーキテクチャでは、プレイ+アッカは、同じノード上に配置されています。
最初にこのテンプレートを作成したときにそのテンプレートを調べました。しかし、私が試しているアーキテクチャーは、同じノード上のplay + akkaであり、その結果、各プレイノードも内部にアクターシステムを持っています。 – dmcqu314