17
votes

Are there any guides or tutorials which explain the possibility to use scala actors remotely? All I have found until now is one example (without comments) but that's hardly enough.

6

6 Answers

10
votes

I have written an article with an example app to explain the use of Remote Actors a bit some time ago.

Well, it has no comments inside the code (maybe you even meant that article), but there are explanations below the code.

3
votes

Just be careful to send messages that are serializable (case classes and case objects are!) and be sure the opposite side can create the class. Watch out for custom ClassLoaders or missing JARs in you classpaths.

1
votes

None of which I am aware. It's pretty much a "hack your way through the jungle" approach. Judging from the API though, things should work pretty much the same as regular actors, for which there exist one or two tutorials (as well as a few books now).

If you do make use of remote actors, we (the community) would certainly welcome such a tutorial from an experienced user!

1
votes

The Akka framework has remote actors. The API is pretty similar to regular scala actors.

They provide some level of automatic clustering as well, but it's not complete.

1
votes

recently there was a guide added on the front page of www.scala-lang.org, here is the link http://www.scala-lang.org/docu/files/actors-api/actors_api_guide.html#

1
votes

Maybe this is a necropost but I was looking for all over and could not find much. Hopefully this will help someone.

I am running Mac OS 10.6.8 and Scala 2.9.0.1. I had problems getting the canonical remote actors example running. I ended up with the following code.

Note: The clear method is just to prevent messages from piling up. It's not critical to the example. Likewise the calls to Thread.sleep are just to make it easier to see what is going on at runtime.

Compile it, then in separate shell instances do:

$> scala Ping

and

$> scala Pong

in any order. You can experiment by killing one of them at a time and tracing the code.

import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._

/** @author Connor Doyle */

// Remote messages must be serializable.
// The easist way to do this is to wrap
// them with a case class
case class Message(text: String)

abstract class PingPongActor extends Actor with App {
    val pingPort = 9000
    val pongPort = 9001
    val delay = 1000
    classLoader = getClass().getClassLoader() // hack!
    start

    // this method consumes all pending messages
    // the library should have implemented an atomic 
    // receiveAndClear operation
    def clear: Unit = receiveWithin(0) {
        case TIMEOUT => ()
        case _ => clear
    }
}

object Ping extends PingPongActor {

    // result of select already lazy, but explicit lazy conveys
    // semantics clearly
    lazy val pong = select(Node("localhost", pongPort), 'pong)

    def act = {
        alive(pingPort)
        register('ping, self)
        loop {
            pong ! Message("ping")
            receiveWithin(delay * 2) {
                case Message(text: String) => {
                    clear
                    println("received: "+text)
                    Thread.sleep(delay) // wait a while
                }
                case TIMEOUT => println("ping: timed out!")
            }
        }
    }
}

object Pong extends PingPongActor {

    lazy val ping = select(Node("localhost", pingPort), 'ping)

    def act = {
        alive(pongPort)
        register('pong, self)
        loop {
            receiveWithin(delay * 2) {
                case Message(text: String) => {
                    println("received: "+text)
                    Thread.sleep(delay) // wait a while
                    clear
                    ping ! Message("pong")
                }
                case TIMEOUT => println("pong: timed out")
            }
        }
    }
}

Cheers!