Having Difficulty working with clusters

Hello

I am tring to run the example at reactivedesignpatterns dot com lectures distributed1.
ClusterMain runs successfully.
Then ClusterWorker gets this error:

Bind failed for TCP channel on endpoint [10.18.1.8:25520]
Address already in use: bind

NOTE: This is the third time I am trying open this issue. Akismet stops it.

ClusterMain code:

package com.example.cluster

import akka.actor.{Actor, ActorLogging, Props, ReceiveTimeout}
import akka.cluster.{Cluster, ClusterEvent}
import com.example.cluster.ClusterReceptionist._
import scala.concurrent.duration.{Duration, DurationInt, FiniteDuration}

class ClusterMain extends Actor with ActorLogging {

val cluster = Cluster(context.system)
cluster.subscribe(self, classOf[ClusterEvent.MemberUp])
cluster.subscribe(self, classOf[ClusterEvent.MemberRemoved])
cluster.join(cluster.selfAddress)

val clusterreceptionist = context.actorOf(Props[ClusterReceptionist], “receptionist”)

context watch(clusterreceptionist)

def getlater(d:FiniteDuration,url: String): Unit = {
import context.dispatcher
context.system.scheduler.scheduleOnce(d,clusterreceptionist,Get(url))
}

def receive: Receive =
{
case ClusterEvent.MemberUp(member)=>
if(member.address!=cluster.selfAddress)
{
getlater(1.seconds,“google.com”)
context.setReceiveTimeout(3.seconds)
}
case Result(url, set) =>
println(set.toVector.sorted.mkString(s"Results for ‘$url’:\n", “\n”, “\n”))
case Failed(url,reason) =>
println(s"Failed to fetch ‘$url’ : $reason\n")
case ReceiveTimeout =>
cluster.leave(cluster.selfAddress)
case ClusterEvent.MemberRemoved(m,_)=>
context.stop(self)

}
}

object ClusterMain extends App {
val main = akka.Main.main(Array(classOf[ClusterMain].getName))
}

ClusterWorker code:

package com.example.cluster

import akka.actor.Actor
import akka.cluster.{Cluster, ClusterEvent}

class ClusterWorker extends Actor {
val cluster = Cluster(context.system)

cluster.subscribe(self, classOf[ClusterEvent.MemberRemoved])

val seedAddress = cluster.selfAddress.copy(port = Some(25520))
cluster.join(seedAddress)

override def receive = {
case ClusterEvent.MemberRemoved(m, _) =>
if (m.address == seedAddress) context.stop(self)
}

override def postStop(): Unit = {
WebScrapper.shutdown()
}

}

object ClusterWorker extends App {
val main = akka.Main.main(Array(classOf[ClusterWorker].getName))
}

ClusterMain conf

akka {
actor {
provider = “akka.cluster.ClusterActorRefProvider”
}

loglevel = “INFO”

cluster {
min-nr-of-members = 2
}
}

ClusterWorker conf:

akka {
actor {
provider = “akka.cluster.ClusterActorRefProvider”
}

remote {
log-remote-lifecycle-events = on
netty.tcp {
port = 0
}
}

loglevel = “INFO”

cluster {
auto-down=on
auto-down-unreachable-after = 10s
}
}

build.sbt :

name := “akka-quickstart-scala”

version := “1.0”

scalaVersion := “2.13.1”

lazy val akkaVersion = “2.6.17”

libraryDependencies ++= Seq(
“com.typesafe.akka” %% “akka-actor-typed” % akkaVersion,
“ch.qos.logback” % “logback-classic” % “1.2.3”,
“com.typesafe.akka” %% “akka-actor-testkit-typed” % akkaVersion % Test,
“com.ning” % “async-http-client” % “1.7.19”,
“com.typesafe.akka” %% “akka-cluster” % akkaVersion,
“org.jsoup” % “jsoup” % “1.11.2”,
“com.typesafe.akka” %% “akka-cluster-typed” % akkaVersion,
“org.scalatest” %% “scalatest” % “3.1.0” % Test
)

Hi Ozcano1,

The reason why it does not work is that since Akka 2.6.0 the default remoting is no longer Netty, but artery-tcp, which means the port config setting Netty port to 0 does not help when trying to run multiple cluster nodes on the same computer. Try looking at the config (and maybe code as well) in akka-samples/application.conf at 2.6 · akka/akka-samples · GitHub for a setup that should work with Akka 2.6

1 Like

Hello Johan

Many thanks for the help. I understand that reactivedesignpatterns dot com is not up to date with the recent developments on Akka (new APIs etc.). Are there more up to date videos or books on Akka which teaches the way reactivedesignpatterns dot com does. I am still studying akka-sample-cluster-scala example you suggested with the help of corresponding documentation at github. It is good but reactivedesignpatterns dot com had more detailed explanation about how code really works.

Best Regards

Özcan Öz

I don’t expect that you will stumble on many more incompatibilities like that.

If you get stuck on something that doesn’t seem to work as described in the videos it could perhaps help to skim the 2.5 to 2.6 migration guide and see if something related to a particular area has some notes: Migration Guide 2.5.x to 2.6.x • Akka Documentation

The reference documentation, while not covering patterns like Rolands lectures, is up to date with the new APIs and has quite a bit of samples, for example the getting started guide is worth a read: Getting Started Guide • Akka Documentation

Ok. Thanks. Kind Regards
Özcan