From 89903c8246ba267fea28738d501e16bc8fe7c8f7 Mon Sep 17 00:00:00 2001 From: lregnier Date: Sun, 23 Jul 2017 19:41:42 -0300 Subject: [PATCH 1/5] Adding cluster features. --- build.sbt | 2 ++ src/main/resources/application.conf | 34 ++++++++++++++++++++-- src/main/scala/HttpServerApp.scala | 22 ++++++++++++-- src/main/scala/services/EventManager.scala | 4 +-- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index dd0812c..68c24be 100644 --- a/build.sbt +++ b/build.sbt @@ -11,6 +11,8 @@ libraryDependencies ++= { val json4sVersion = "3.5.0" Seq( "com.typesafe.akka" %% "akka-actor" % akkaVersion, + "com.typesafe.akka" %% "akka-cluster" % akkaVersion, + "com.typesafe.akka" %% "akka-cluster-tools" % akkaVersion, "com.typesafe.akka" %% "akka-http" % akkaHttpVersion, "com.typesafe.akka" %% "akka-stream" % akkaVersion, "de.heikoseeberger" %% "akka-http-json4s" % akkaHttpJson4sVersion, diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 395dcef..251e3d7 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1,10 +1,38 @@ akka { - loglevel = DEBUG - stdout-loglevel = DEBUG + loglevel = INFO + stdout-loglevel = INFO loggers = ["akka.event.Logging$DefaultLogger"] + + actor { + provider = "cluster" + } + + remote { + log-remote-lifecycle-events = off + + artery { + enabled = on + canonical.hostname = "127.0.0.1" + canonical.port = 2551 + canonical.port = ${?akka.port} + } + } + + cluster { + seed-nodes = [ + "akka://reactive-tickets-system@127.0.0.1:2551", + "akka://reactive-tickets-system@127.0.0.1:2552"] + + # auto downing is NOT safe for production deployments. + # you may want to use it during development, read more about it in the docs. + # + auto-down-unreachable-after = 10s + } + } http { host = "0.0.0.0" port = 9000 -} \ No newline at end of file + port = ${?http.port} +} diff --git a/src/main/scala/HttpServerApp.scala b/src/main/scala/HttpServerApp.scala index 4fef9a3..f9552a4 100644 --- a/src/main/scala/HttpServerApp.scala +++ b/src/main/scala/HttpServerApp.scala @@ -1,4 +1,5 @@ -import akka.actor.ActorSystem +import akka.actor.{ActorSystem, PoisonPill} +import akka.cluster.singleton.{ClusterSingletonManager, ClusterSingletonManagerSettings, ClusterSingletonProxy, ClusterSingletonProxySettings} import akka.event.Logging import akka.http.scaladsl.Http import akka.http.scaladsl.server.Directives @@ -11,7 +12,7 @@ import scala.concurrent.Await import scala.concurrent.duration._ trait AkkaModule { - implicit val system = ActorSystem("akka-tickets-system") + implicit val system = ActorSystem("reactive-tickets-system") implicit val executor = system.dispatcher implicit val materializer = ActorMaterializer() } @@ -29,7 +30,22 @@ trait SettingsModule { } trait ServicesModule { self: AkkaModule => - val ticketSellerSupervisor = system.actorOf(TicketSellerSupervisor.props(), TicketSellerSupervisor.Name) + // Initiates singleton TicketSellerSupervisor in the Cluster + system.actorOf( + ClusterSingletonManager.props( + singletonProps = TicketSellerSupervisor.props(), + terminationMessage = PoisonPill, + settings = ClusterSingletonManagerSettings(system).withSingletonName(TicketSellerSupervisor.Name)), + name = s"${TicketSellerSupervisor.Name}-singleton") + + // Initiates proxy for singleton + val ticketSellerSupervisor = + system.actorOf( + ClusterSingletonProxy.props( + singletonManagerPath = "/user/consumer", + settings = ClusterSingletonProxySettings(system)), + name = s"${TicketSellerSupervisor.Name}-proxy") + val boxOffice = system.actorOf(EventManager.props(ticketSellerSupervisor), EventManager.Name) } diff --git a/src/main/scala/services/EventManager.scala b/src/main/scala/services/EventManager.scala index 9ca5b22..8b444df 100644 --- a/src/main/scala/services/EventManager.scala +++ b/src/main/scala/services/EventManager.scala @@ -62,11 +62,11 @@ class EventManager(ticketSellerSupervisor: ActorRef) extends Actor { } case ListEvents => { - def listShows(): Seq[Event] = { + def listEvents(): Seq[Event] = { events.toSeq } - sender ! listShows() + sender ! listEvents() } case msg @ EventMessage(name, Cancel) => From 5e82f3b3ffee29caf60dc2cbe6e1baf790dc212c Mon Sep 17 00:00:00 2001 From: lregnier Date: Sun, 23 Jul 2017 19:52:59 -0300 Subject: [PATCH 2/5] Merge branch 'develop' into feature/1-akka-cluster-singleton # Conflicts: # src/main/resources/application.conf --- src/main/resources/application.conf | 32 +++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 395dcef..119531d 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1,10 +1,38 @@ akka { - loglevel = DEBUG - stdout-loglevel = DEBUG + loglevel = INFO + stdout-loglevel = INFO loggers = ["akka.event.Logging$DefaultLogger"] + + actor { + provider = "cluster" + } + + remote { + log-remote-lifecycle-events = off + + artery { + enabled = on + canonical.hostname = "127.0.0.1" + canonical.port = 2551 + canonical.port = ${?akka.port} + } + } + + cluster { + seed-nodes = [ + "akka://reactive-tickets-system@127.0.0.1:2551", + "akka://reactive-tickets-system@127.0.0.1:2552"] + + # auto downing is NOT safe for production deployments. + # you may want to use it during development, read more about it in the docs. + # + auto-down-unreachable-after = 10s + } + } http { host = "0.0.0.0" port = 9000 + port = ${?http.port} } \ No newline at end of file From 13c76aa3d682fca52f1f8bbdd1b408ed5a6007ad Mon Sep 17 00:00:00 2001 From: lregnier Date: Sun, 23 Jul 2017 20:12:37 -0300 Subject: [PATCH 3/5] Fixing singletonManagerPath. --- src/main/scala/HttpServerApp.scala | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/scala/HttpServerApp.scala b/src/main/scala/HttpServerApp.scala index f9552a4..fc13d5c 100644 --- a/src/main/scala/HttpServerApp.scala +++ b/src/main/scala/HttpServerApp.scala @@ -31,22 +31,23 @@ trait SettingsModule { trait ServicesModule { self: AkkaModule => // Initiates singleton TicketSellerSupervisor in the Cluster - system.actorOf( - ClusterSingletonManager.props( - singletonProps = TicketSellerSupervisor.props(), - terminationMessage = PoisonPill, - settings = ClusterSingletonManagerSettings(system).withSingletonName(TicketSellerSupervisor.Name)), - name = s"${TicketSellerSupervisor.Name}-singleton") + val ticketSellerSupervisorSingleton = + system.actorOf( + ClusterSingletonManager.props( + singletonProps = TicketSellerSupervisor.props(), + terminationMessage = PoisonPill, + settings = ClusterSingletonManagerSettings(system).withSingletonName(TicketSellerSupervisor.Name)), + name = s"${TicketSellerSupervisor.Name}-singleton") // Initiates proxy for singleton - val ticketSellerSupervisor = - system.actorOf( - ClusterSingletonProxy.props( - singletonManagerPath = "/user/consumer", - settings = ClusterSingletonProxySettings(system)), - name = s"${TicketSellerSupervisor.Name}-proxy") + val ticketSellerSupervisorSingletonProxy = + system.actorOf( + ClusterSingletonProxy.props( + singletonManagerPath = ticketSellerSupervisorSingleton.path.toStringWithoutAddress, + settings = ClusterSingletonProxySettings(system).withSingletonName(TicketSellerSupervisor.Name)), + name = s"${TicketSellerSupervisor.Name}-proxy") - val boxOffice = system.actorOf(EventManager.props(ticketSellerSupervisor), EventManager.Name) + val boxOffice = system.actorOf(EventManager.props(ticketSellerSupervisorSingletonProxy), EventManager.Name) } trait EndpointsModule { self: AkkaModule with ServicesModule => From ba59d1f215010cc2fa5ec844e32af9ce85259084 Mon Sep 17 00:00:00 2001 From: lregnier Date: Sun, 23 Jul 2017 20:25:14 -0300 Subject: [PATCH 4/5] Fix rename for EventMaanger. --- src/main/scala/HttpServerApp.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/HttpServerApp.scala b/src/main/scala/HttpServerApp.scala index fc13d5c..a643742 100644 --- a/src/main/scala/HttpServerApp.scala +++ b/src/main/scala/HttpServerApp.scala @@ -47,7 +47,7 @@ trait ServicesModule { self: AkkaModule => settings = ClusterSingletonProxySettings(system).withSingletonName(TicketSellerSupervisor.Name)), name = s"${TicketSellerSupervisor.Name}-proxy") - val boxOffice = system.actorOf(EventManager.props(ticketSellerSupervisorSingletonProxy), EventManager.Name) + val eventManager = system.actorOf(EventManager.props(ticketSellerSupervisorSingletonProxy), EventManager.Name) } trait EndpointsModule { self: AkkaModule with ServicesModule => @@ -55,7 +55,7 @@ trait EndpointsModule { self: AkkaModule with ServicesModule => val routes = pathPrefix("api") { - EventHttpEndpoint(boxOffice).routes + EventHttpEndpoint(eventManager).routes } } From 1ff25e671f658cb3fcd004f078f9a61a86cdbd4c Mon Sep 17 00:00:00 2001 From: lregnier Date: Thu, 27 Jul 2017 18:19:10 -0300 Subject: [PATCH 5/5] Updating singleton names. --- src/main/scala/HttpServerApp.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/HttpServerApp.scala b/src/main/scala/HttpServerApp.scala index 2299096..eef6f27 100644 --- a/src/main/scala/HttpServerApp.scala +++ b/src/main/scala/HttpServerApp.scala @@ -51,16 +51,16 @@ trait ServicesModule { self: AkkaModule with PersistenceModule => ClusterSingletonManager.props( singletonProps = TicketSellerSupervisor.props(), terminationMessage = PoisonPill, - settings = ClusterSingletonManagerSettings(system).withSingletonName(TicketSellerSupervisor.Name)), - name = s"${TicketSellerSupervisor.Name}-singleton") + settings = ClusterSingletonManagerSettings(system).withSingletonName(s"${TicketSellerSupervisor.Name}-singleton")), + name = s"${TicketSellerSupervisor.Name}-singleton-manager") // Initiates proxy for singleton val ticketSellerSupervisorSingletonProxy = system.actorOf( ClusterSingletonProxy.props( singletonManagerPath = ticketSellerSupervisorSingleton.path.toStringWithoutAddress, - settings = ClusterSingletonProxySettings(system).withSingletonName(TicketSellerSupervisor.Name)), - name = s"${TicketSellerSupervisor.Name}-proxy") + settings = ClusterSingletonProxySettings(system).withSingletonName(s"${TicketSellerSupervisor.Name}-singleton")), + name = s"${TicketSellerSupervisor.Name}-singleton-proxy") val eventManager = system.actorOf(EventManager.props(eventRepository, ticketSellerSupervisorSingletonProxy), EventManager.Name) }