Actor Name is not Unique InvalidActorNameException - scala

My environment is eclipse, play, akka, and scala. I am getting an error when trying to create a remote master akka actor.
I am not sure why I am getting this error:
[InvalidActorNameException: actor name hello is not unique!]
When the user submits their form, calculate is called:
options => {
this.calculate(options.numWorkers.toInt, options.numElements.toInt, options.numMessages.toInt)
//Redirect(routes.Application.)
Ok(html.form(this.optionsForm))
}
Here is the code where I create the actor
val master = RemoteSystem.system.actorOf(Props[Master], "hello")
I also only create one instance of this actor and have tried many other names such as master, Master, and master1983274612987346198356.
Master is defined as:
class Master extends Actor {
var pi: Double = _
var nrOfResults: Int = _
var start: Long = _
def receive = {
case calculate(numWorkers, numElements, numMessages) =>{
for (i <- 0 until numWorkers) {
val worker = RemoteSystem.system.actorOf(Props[Worker], "Worker")
for(j <- 0 until numMessages)
{
worker ! Work(0, numElements)
}
}
}
case PiResult(start, numTerms, acc) => println("Pi Result: " + acc)
}
override def preStart() {
start = System.currentTimeMillis
}
override def postStop() {
println(
"\n\tCalculation time: \t%s millis".format(System.currentTimeMillis - start))
}
}
And the actor system is:
object RemoteSystem {
val system = ActorSystem(
"RemoteCreation", ConfigFactory.load.getConfig("remotecreation"))
}
Where remotecreation is defined as:
remotecreation{
include "common"
akka {
actor{
deployment{
/Worker{
remote="akka://Pi#10.0.100.254:2552"
}
}
}
remote.netty.port = 2554
}
}

It seems in the following code that you are creating many workers with the same name "Worker":
for (i <- 0 until numWorkers) {
val worker = RemoteSystem.system.actorOf(Props[Worker], "Worker")
for(j <- 0 until numMessages)
{
worker ! Work(0, numElements)
}
}
You need to move the actor creation code (see this doc):
class Master extends Actor {
val worker = RemoteSystem.system.actorOf(Props[Worker], "Worker")
...
}

Related

AKKA persistent actor doesn't receive command messages in the receive command function

I am trying to use AKKA persistence together with the JDBC plugin. However, when experimenting with the persistent actors I face the problem that my persistent actor does not receive the messages it should receive.
Here is my application.conf file I use for the JDBC plugin.
akka {
loglevel = DEBUG
actor {
#provider = cluster
}
persistence {
journal.plugin = "jdbc-journal"
snapshot-store.plugin = "jdbc-snapshot-store"
}
}
jdbc-journal {
slick = ${slick}
}
# the akka-persistence-snapshot-store in use
jdbc-snapshot-store {
slick = ${slick}
}
jdbc-read-journal {
slick = ${slick}
}
slick {
profile = "slick.jdbc.MySQLProfile$"
dataSourceClass = "slick.jdbc.DriverDataSource"
db {
dataSourceClass = "slick.jdbc.DriverDataSource"
driver = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/db_persistence"
user = "root"
password = ""
numThreads = 5
maxConnections = 5
minConnections = 1
}
}
This is the code of my persistent actor (based on the AKKA documentation code)
case class Cmd(data: String)
case class Evt(data: String)
case class ExampleState(events: List[String] = Nil) {
def updated(evt: Evt): ExampleState = copy(evt.data :: events)
def size: Int = events.length
override def toString: String = events.reverse.toString
}
class ExampleActor extends PersistentActor {
override def persistenceId = "sample-id-1"
var state = ExampleState()
def updateState(event: Evt): Unit = {
state = state.updated(event)
}
def numEvents =
state.size
override def receiveRecover: Receive = {
case evt: Evt => updateState(evt)
case SnapshotOffer(_, snapshot: ExampleState) => state = snapshot
}
val snapShotInterval = 1000
val receiveCommand: Receive = {
case Cmd(data) => {
println("in the command code block")
persist(Evt(s"${data}-${numEvents}")) { event => {
updateState(event)
context.system.eventStream.publish(event)
if (lastSequenceNr % snapShotInterval == 0 && lastSequenceNr != 0)
saveSnapshot(state)
}
}
}
case "print"=>println(state)
}
}
lastly, my test where I find the problem.
"The persistent actor" should {
"Receive Command" in {
val persistentActor = system.actorOf(Props[ExampleActor](),"persistentActorOne")
Thread.sleep(2000)
println("before the send")
persistentActor ! Cmd("foo")
persistentActor ! Cmd("bar")
persistentActor ! Cmd("fizz")
persistentActor ! Cmd("buzz")
persistentActor ! "print"
Thread.sleep(10000)
println("after messages should be sent and received")
}
}
}
Can anybody see the reason why my persistent actor won't receive my messages/commands?
Thanks in advance!

Why is my router not receiving check-in events?

I'm starting to explore the new Akka Typed API. I'm trying to run an updated version of the random router from this blog post.
My router is largely the same:
import java.util.concurrent.ThreadLocalRandom
import akka.actor.Address
import akka.actor.typed.{ActorRef, Behavior}
import akka.actor.typed.receptionist.{Receptionist, ServiceKey}
import akka.actor.typed.scaladsl.Behaviors
import akka.cluster.ClusterEvent.{ReachabilityEvent, ReachableMember, UnreachableMember}
import akka.cluster.typed.{Cluster, Subscribe}
object RandomRouter {
private final case class WrappedReachabilityEvent(event: ReachabilityEvent)
// subscribes to cluster reachability events and
// avoids routees that are unreachable
def clusterRouter[T](serviceKey: ServiceKey[T]): Behavior[T] =
Behaviors.setup[Any] { ctx ⇒
ctx.system.receptionist ! Receptionist.Subscribe(serviceKey, ctx.self)
val cluster = Cluster(ctx.system)
// typically you have to map such external messages into this
// actor's protocol with a message adapter
val reachabilityAdapter: ActorRef[ReachabilityEvent] = ctx.messageAdapter(WrappedReachabilityEvent.apply)
cluster.subscriptions ! Subscribe(reachabilityAdapter, classOf[ReachabilityEvent])
def routingBehavior(routees: Vector[ActorRef[T]], unreachable: Set[Address]): Behavior[Any] =
Behaviors.receive { (ctx, msg) ⇒
msg match {
case serviceKey.Listing(services) ⇒
if (services.isEmpty) {
ctx.log.info("Found no services")
} else {
ctx.log.info(s"Found services: ${services.map(_.path.name).mkString(", ")}")
}
routingBehavior(services.toVector, unreachable)
case WrappedReachabilityEvent(event) => event match {
case UnreachableMember(m) =>
ctx.log.warning(s"Member ${m.address} has become unreachable")
routingBehavior(routees, unreachable + m.address)
case ReachableMember(m) =>
ctx.log.info(s"Member ${m.address} has become reachable again")
routingBehavior(routees, unreachable - m.address)
}
case other: T #unchecked ⇒
if (routees.isEmpty)
Behaviors.unhandled
else {
val reachableRoutes =
if (unreachable.isEmpty) routees
else routees.filterNot { r => unreachable(r.path.address) }
val i = ThreadLocalRandom.current.nextInt(reachableRoutes.size)
reachableRoutes(i) ! other
Behaviors.same
}
}
}
routingBehavior(Vector.empty, Set.empty)
}.narrow[T]
}
And my cluster spins off dummy actors:
object DummyActor {
def behavior[T](serviceKey: ServiceKey[T]): Behavior[Any] = Behaviors.setup { ctx =>
ctx.log.info("Woohoo, I'm alive!")
Behaviors.empty
}
}
with the following:
object MyCluster {
val serviceKey: ServiceKey[String] = ServiceKey[String]("cluster")
val behavior: Behavior[String] = Behaviors.setup { ctx =>
(1 to 5).foreach { i =>
ctx.log.info("I'm so sleepy...")
Thread.sleep(500)
ctx.log.info(s"Spawning actor #$i")
ctx.spawnAnonymous(DummyActor.behavior(serviceKey))
ctx.log.info("I'm tired again...")
Thread.sleep(500)
}
val router = ctx.spawn(RandomRouter.clusterRouter(serviceKey), "router")
Behaviors.stopped
}
}
When I run the following main, I always see "Found no services" in my log, indicating what I believe to mean that none of my dummy actors registered with the cluster receptionist.
import akka.actor.typed.ActorSystem
object Main extends App {
val system = ActorSystem(MyCluster.behavior, "cluster-system")
}
What am I missing? I'm using Akka 2.5.12.
The dummy actors need to register! It doesn't happen automatically. This was solved by adding the following line in the setup block:
ctx.system.receptionist ! Receptionist.Register(serviceKey, ctx.self)
object DummyActor {
def behavior[T](serviceKey: ServiceKey[T]): Behavior[Any] = Behaviors.setup { ctx =>
ctx.system.receptionist ! Receptionist.Register(serviceKey, ctx.self)
ctx.log.info("Woohoo, I'm alive!")
Behaviors.empty
}
}

Implement Actor model without Akka in Scala

I am doing my small research that implement Actor without Akka
I found one implementation of Actor in Scala. (How to implement actor model without Akka?)
It's very simple. Because I have not enough reputation to add the comment, so I create this question.
I wonder if I use Actor like below.
1/ How can I shutdown that actor from main thread?
2/ How can I add feature similar to Akka, like parent actor, kill request, and become method?
import scala.concurrent._
trait Actor[T] {
implicit val context = ExecutionContext.fromExecutor(java.util.concurrent.Executors.newFixedThreadPool(1))
def receive: T => Unit
def !(m: T) = Future { receive(m) }
}
This is my own example when trying to adapt the above code snippet
import scala.concurrent._
/**
* Created by hminle on 10/21/2016.
*/
trait Message
case class HelloMessage(hello: String) extends Message
case class GoodByeMessage(goodBye: String) extends Message
object State extends Enumeration {
type State = Value
val Waiting, Running, Terminating = Value
}
trait Actor[T] {
implicit val context = ExecutionContext.fromExecutor(java.util.concurrent.Executors.newFixedThreadPool(1))
private var state: State.State = State.Waiting
def handleMessage: T => Unit ={
if(state == State.Waiting) handleMessageWhenWaiting
else if(state == State.Running) handleMessageWhenRunning
else handleMessageWhenTerminating
}
def !(m: T) = Future {handleMessage(m)}
def handleMessageWhenWaiting: T => Unit
def handleMessageWhenRunning: T => Unit
def handleMessageWhenTerminating: T => Unit
def transitionTo(destinationState: State.State): Unit = {
this.state = destinationState
}
}
class Component1 extends Actor[Message]{
def handleMessageWhenRunning = {
case HelloMessage(hello) => {
println(Thread.currentThread().getName + hello)
}
case GoodByeMessage(goodBye) => {
println(Thread.currentThread().getName + goodBye)
transitionTo(State.Terminating)
}
}
def handleMessageWhenWaiting = {
case m => {
println(Thread.currentThread().getName + " I am waiting, I am not ready to run")
transitionTo(State.Running)
}
}
def handleMessageWhenTerminating = {
case m => {
println(Thread.currentThread().getName + " I am terminating, I cannot handle any message")
//need to shutdown here
}
}
}
class Component2(component1: Actor[Message]) extends Actor[Message]{
def handleMessageWhenRunning = {
case HelloMessage(hello) => {
println(Thread.currentThread().getName + hello)
component1 ! HelloMessage("hello 1")
}
case GoodByeMessage(goodBye) => {
println(Thread.currentThread().getName + goodBye)
component1 ! GoodByeMessage("goodbye 1")
transitionTo(State.Terminating)
}
}
def handleMessageWhenWaiting = {
case m => {
println(Thread.currentThread().getName + " I am waiting, I am not ready to run")
transitionTo(State.Running)
}
}
def handleMessageWhenTerminating = {
case m => {
println(Thread.currentThread().getName + " I am terminating, I cannot handle any message")
//need to shutdown here
}
}
}
object ActorExample extends App {
val a = new Component1
val b = new Component2(a)
b ! HelloMessage("hello World 2")
b ! HelloMessage("hello World 2, 2nd")
b ! GoodByeMessage("Good bye 2")
println(Thread.currentThread().getName)
}
You can look at Actor model implementation in scalazand take ideas from it, source code in scalaz actor is easier for insight than akka. You have freedom of choice about architecture: you can use mailboxes based on ConcurrentLinkedQueue like in Akka, use CAS for AtomicReffernce like in scalaz, in your case you use Future mechanism. IMO, you must write a context of your actor system, so solve first and second items in your question it's the variant of ActorContext:
val contextStack = new ThreadLocal[List[ActorContext]]
and shutdown can look like this:
1.
case Kill ⇒ throw new ActorKilledException("Kill")
case PoisonPill ⇒ self.stop()
2. For storing parent actor and similar task, you must store reference on them:
def parent: ActorRef
it's hard to say about advantages of every technique (CAS, mailboxes), it's possible variants to your research.

Scala actors left hanging

I am spawning a small number of actors to fetch, process and save RSS feed items to a database. This is done through a main method of an object running on cron. I create these actors and dole out jobs to them as they complete the previous job assigned to them. My main class spawns a single actor, the one that doles out jobs to a pool of actors. Eventually the main method seems to hang. It doesn't exit, but execution halts on all the actors. My CTO believes the main is exiting before the actors complete their work and leaving them, but I am not convinced that's the case. I receive no success exit on main (no exit at all).
Essentially I'm wondering how to debug these actors, and what possible reason could cause this to happen. Will main exit before actors have completed their execution (and if it does, does that matter?) From what I can tell actors using receive are mapped 1-to-1 to threads, correct? Code is below. Please ask any follow-up questions, help is greatly appreciated. I know I may not have provided sufficient detail, I'm new to scala and actors and will update as needed.
object ActorTester {
val poolSize = 10
var pendingQueue :Set[RssFeed] = RssFeed.pendingQueue
def main(args :Array[String]) {
val manager = new SpinnerManager(poolSize, pendingQueue)
manager.start
}
}
case object Stop
class SpinnerManager(poolSize :Int = 1, var pendingQueue :Set[RssFeed]) extends Actor {
val pool = new Array[Spinner](poolSize)
override def start() :Actor = {
for (i <- 0 to (poolSize - 1)) {
val spinner = new Spinner(i)
spinner.start()
pool(i) = spinner
}
super.start
}
def act() {
for {
s <- pool
if (!pendingQueue.isEmpty)
} {
s ! pendingQueue.head
pendingQueue = pendingQueue.tail
}
while(true) {
receive {
case id :Int => {
if (!pendingQueue.isEmpty) {
pool(id) ! pendingQueue.head
pendingQueue = pendingQueue.tail
} else if ((true /: pool) { (done, s) => {
if (s.getState != Actor.State.Runnable) {
val exited = future {
s ! Stop
done && true
}
exited()
} else {
done && false
}
}}) {
exit
}
}
}
}
}
}
class Spinner(id :Int) extends Actor {
def act() {
while(true) {
receive {
case dbFeed :RssFeed => {
//process rss feed
//this has multiple network requests, to the original blogs, bing image api
//our instance of solr - some of these spawn their own actors
sender ! id
}
case Stop => exit
}
}
}
}
For one thing you're making a tiny but important mistake when you're folding left in order to determine whether all Spinner actors have "terminated" or not. What you should do is evaluate to done && true resp. done && false at the end of the if cases, but currently you just say true resp. false without respect to done.
For example, imagine having 4 Spinner actors where the first and second ones were Runnable, the third one not, and the fourth one Runnable again. In that case the result of your foldleft would be true in spite of the fact that the third actor hasn't finished yet. If you were using a logical &&, you'd get the correct result.
This is possibily also what causes your application to hang.
EDIT: There also was an issue wrt a race condition. The following code works now, hope it helps. Anyway, I was wondering, doesn't Scala's actor implementation automatically make use of worker threads?
import actors.Actor
import scala.collection.mutable.Queue
case class RssFeed()
case class Stop()
class Spinner(id: Int) extends Actor {
def act() {
loop {
react {
case dbFeed: RssFeed => {
// Process RSS feed
sender ! id
}
case Stop => exit()
}
}
}
}
class SpinnerManager(poolSize: Int, pendingQueue: Queue[RssFeed]) extends Actor {
val pool = Array.tabulate(poolSize)(new Spinner(_).start())
def act() {
for (s <- pool; if (!pendingQueue.isEmpty)) {
pendingQueue.synchronized {
s ! pendingQueue.dequeue()
}
}
loop {
react {
case id: Int => pendingQueue.synchronized {
if (!pendingQueue.isEmpty) {
Console println id
pool(id) ! pendingQueue.dequeue()
} else {
if (pool forall (_.getState != Actor.State.Runnable)) {
pool foreach (_ ! Stop)
exit()
}
}
}
}
}
}
}
object ActorTester {
def main(args: Array[String]) {
val poolSize = 10
val pendingQueue: Queue[RssFeed] = Queue.tabulate(100)(_ => RssFeed())
new SpinnerManager(poolSize, pendingQueue).start()
}
}
So after several days of debugging I've solved this issue. fotNelton's code suggestions were very helpful in doing so, so I've given him a vote. However, they didn't address the problem itself. What I've found is that if you are running this in a main method then if the parent actors exit before their child actors then the program will hang forever and never exit, still holding all of its memory. In the process of handling the RSS feed, a Fetcher would spawn actors and send them messages to do things involving network requests. These actors need to complete their work before the parent actor quits. Fetcher wouldn't wait for these actors to finish though, once he sent the message he would just move on. So he would tell manager he was finished before his child actors had finished all their work. To deal with this, one option would be to use futures and wait until the actors are done (pretty slow). My solution was to create services accessible via URL (POST to a service that has an actor waiting to react). The service would respond right away, and send a message to its own actor. Thus the actors can quit once they send the request to the service, and don't need to spawn any other actors.
object FeedFetcher {
val poolSize = 10
var pendingQueue :Queue[RssFeed] = RssFeed.pendingQueue
def main(args :Array[String]) {
new FetcherManager(poolSize, pendingQueue).start
}
}
case object Stop
class FetcherManager(poolSize :Int = 1, var pendingQueue :Queue[RssFeed]) extends Actor {
val pool = new Array[Fetcher](poolSize)
var numberProcessed = 0
override def start() :Actor = {
for (i <- 0 to (poolSize - 1)) {
val fetcher = new Fetcher(i)
fetcher.start()
pool(i) = fetcher
}
super.start
}
def act() {
for {
f <- pool
if (!pendingQueue.isEmpty)
} {
pendingQueue.synchronized {
f ! pendingQueue.dequeue
}
}
loop {
reactWithin(10000L) {
case id :Int => pendingQueue.synchronized {
numberProcessed = numberProcessed + 1
if (!pendingQueue.isEmpty) {
pool(id) ! pendingQueue.dequeue
} else if ((true /: pool) { (done, f) => {
if (f.getState == Actor.State.Suspended) {
f ! Stop
done && true
} else if (f.getState == Actor.State.Terminated) {
done && true
} else {
false
}
}}) {
pool foreach { f => {
println(f.getState)
}}
println("Processed " + numberProcessed + " feeds total.")
exit
}
}
case TIMEOUT => {
if (pendingQueue.isEmpty) {
println("Manager just woke up from timeout with all feeds assigned.")
pool foreach { f => {
if (f.getState == Actor.State.Suspended) {
println("Sending Stop to Fetcher " + f.id)
f ! Stop
}
}}
println("Checking state of all Fetchers for termination.")
if ((true /: pool) { (done, f) => {
done && (f.getState == Actor.State.Terminated)
}}) {
exit
}
}
}
}
}
}
}
class Fetcher(val id :Int) extends Actor {
var feedsIveDone = 0
def act() {
loop {
react {
case dbFeed :RssFeed => {
println("Fetcher " + id + " starting feed")
//process rss feed here
feedsIveDone = feedsIveDone + 1
sender ! id
}
case Stop => {
println(id + " exiting")
println(feedsIveDone)
exit
}
}
}
}

Make Scala Remote Actors more stable

I was writing a little test program to try out some things with Remote Actors that I was going to need in a Scala project.
The basic goal was to write a test application of one server that could handle a bunch of clients and more important clients that can send multiple messages at the same time (like pings, requests for updates and user induced requests for data)
What I came up with was this:
brief overview: the client starts 3 different actors which again start actors in while loops with different offsets in order to simulate rather random messages.
import scala.actors.remote.RemoteActor
import scala.actors.remote.Node
import scala.actors.Actor
trait Request
trait Response
case object WhoAmI extends Request
case class YouAre(s:String) extends Response
case object Ping extends Request
case object Pong extends Response
case class PrintThis(s:String) extends Request
case object PrintingDone extends Response
object Server {
def main(args: Array[String]) {
val server = new Server
server.start
}
}
class Server extends Actor {
RemoteActor.alive(12345)
RemoteActor.register('server, this)
var count:Int = 0
def act() {
while(true) {
receive {
case WhoAmI => {
count += 1
sender ! YouAre(count.toString)
}
case Ping => sender ! Pong
case PrintThis(s) => {
println(s)
sender ! PrintingDone
}
case x => println("Got a bad request: " + x)
}
}
}
}
object Act3 extends scala.actors.Actor {
def act = {
var i = 0
Thread.sleep(900)
while (i <= 12) {
i += 1
val a = new Printer
a.start
Thread.sleep(900)
}
}
}
class Printer extends scala.actors.Actor {
def act = {
val server = RemoteActor.select(Node("localhost",12345), 'server)
server ! PrintThis("gagagagagagagagagagagagaga")
receive {
case PrintingDone => println("yeah I printed")
case _ => println("got something bad from printing")
}
}
}
object Act2 extends scala.actors.Actor {
def act = {
var i = 0
while (i < 10) {
i+=1
val a = new Pinger
a.start
Thread.sleep(700)
}
}
}
class Pinger extends scala.actors.Actor {
def act = {
val server = RemoteActor.select(Node("localhost",12345), 'server)
server ! Ping
receive {
case Pong => println("so I pinged and it fits")
case x => println("something wrong with ping. Got " + x)
}
}
}
object Act extends scala.actors.Actor {
def act = {
var i = 0
while(i < 10) {
i+=1
val a = new SayHi
a.start()
Thread.sleep(200)
}
}
}
class SayHi extends scala.actors.Actor {
def act = {
val server = RemoteActor.select(Node("localhost",12345), 'server)
server ! "Hey!"
}
}
object Client {
def main(args: Array[String]) {
Act.start()
//Act2.start()
Act3.start()
}
}
The problem is that things don't run as smoothly as I'd expect them to:
when I start only one of the client actors (by commenting the others out as I did with Act2in Client) things usually but not always go well. If I start two or more actors, quite often the printouts appear in bulk (meaning: there's nothing happening at once and then the printouts appear rather fast). Also the client sometimes terminates and sometimes doesn't.
This may not be the biggest problems but they're enough to make me feel quite uncomfortable. I did a lot of reading on Actors and Remote Actors but I find the available info rather lacking.
Tried to add exit statements where ever it seemed fit. But that didn't help.
Has anybody got an idea what I'm doing wrong? Any general tricks here? Some dos and donts?
My guess is that your issues stem from blocking your actor's threads by using receive and Thread.sleep. Blocking operations consume threads in the actors' thread pool, which can prevent other actors from executing until new threads are added to the pool. This question may provide some additional insight.
You can use loop, loopWhile, react, and reactWithin to rewrite many of your actors to use non-blocking operations. For example
import scala.actors.TIMEOUT
object Act extends scala.actors.Actor {
def act = {
var i = 0
loopWhile(i < 10) {
reactWithin(200) { case TIMEOUT =>
i+=1
val a = new SayHi
a.start()
}
}
}
}
Of course, you can eliminate some boilerplate by writing your own control construct:
def doWithin(msec: Long)(f: => Unit) = reactWithin(msec) { case TIMEOUT => f }
def repeat(times: Int)(f: => Unit) = {
var i = 0
loopWhile(i < times) {
f
i+=1
}
}
This would allow you to write
repeat(10) {
doWithin(200) {
(new SayHi).start
}
}
You may try Akka actors framework instead http://akkasource.org/