1
votes

I'm new to scala and I'm trying to write a program in scala which creates multiple (say, 30) actors and passes messages between them.

Below is what i have managed till now:

 import scala.actors.Actor
 import scala.util.Random

    class MyActor(val id:Int, val N:Int) extends Actor {
        def act() {
            println ("Starting actor: " + id)    

            /**
                 react{

                        case str : String =>
                              println("Received Msg: " + str)

                              val randNo : Int = Random.nextInt(N)
                              println("Actor " + id + " Picking a random actor: " + randNo) 

            // Here, I should forward the message received to the ALREADY created and started actors    
                             // val objActor = new MyActor(randNo : Int, N : Int)
                             // objActor.start
                             // objActor ! str
                        }
            */
        }
    }

    object Main {

    def main(args:Array[String]) {

        if(args.length == 0)
        {
            println("Usage scala Main <numNodes>")
            sys.exit()
        }

        val N : Int = (args(0)).toInt

        // Starting all actors

         for (i: Int <- 0 to N-1) {
                val a = new MyActor(i : Int, N : Int)
                println ("About to start actor " + a.id)
                a.start 
         //   a!"Broadcast this msg to all actors"
         } 
      }
    }

The objective of the program is to create multiple actors and forward a string from one actor to another.

The above code creates 'N' number of actors given as command line argument. These actors are created and started by the object Main. Main should send a message to ONLY ONE of the above created actors. The actor which receives the message from the Main should forward the same message to another ALREADY created/started actor.

Is this possible? If so, can you please guide me on the right direction?

Thanks in advance, MS

2

2 Answers

5
votes

First off, I would suggest checking out Akka actors, soon to replace Scala actors in Scala 2.10 which is hopefully coming out in the next few months.

That being said, it definitely is possible, the workflow would go something like this (in Akka at least):

  1. Create an ActorSystem in your main method.
  2. Spawn Actor as desired within the ActorSystem via the actorOf method, which will return an ActorRef object.
  3. Pick one of these ActorRef's to send the message to.

In the Actor implementation, somehow make the Actor aware of the others (perhaps via the constructor), and figure out how you want the propagate the String throughout the system (on this note, I generally prefer using Scala case classes as messages).

This sort of sounds like a state machine like system - one idea off the top of my head that I've been playing with is to treat the ActorSystem as a graph entity, meaning for each Actor instance you pass it a list of it's neighbors (perhaps as a Vector[ActorRef]).

You can also check out the new Actors DSL the Akka team recently introduced.

For learning more about Akka, I recommend the resources:

  1. Jonas Bonér's recent talk at NY Scala introducing Akka
  2. Akka in Action (MEAP)
0
votes

I found a way to do the above stated problem in scala itself by using an array of actors. since all the actors are going to perform the same operation (i.e.,) forwarding the message, it is enough to create multiple instances of MyActor. Thanks a lot!