How do I disconnect a Scala Remote Actor?

In scala it is very easy to make a connection to a remote actor, but the documentation does not tell me anything about disconnecting. Simply throwing away the reference does not work, because remote actors are actors, so these won't be collected until stopped. So how do I disconnect?

This does not Terminate after exit:

import actors.{DaemonActor,remote}
import remote.{RemoteActor,Node}

object SimpleClient{
    val messageHandler = new DaemonActor{
        def act{
            loop{
                react{
                    case message:String =>
                        println("got message: " + message)
                    case _ =>
                }
            }
        }
        start
    }

    def main(args:Array[String]){
        val server = RemoteActor.select(Node("localhost",9999),'server)
        server.send('Connect,messageHandler)

        var exit = false
        while(!exit){
            val message = Console.readLine
            if(message == "exit" || message == "quit") {
                exit = true
                server ! 'Disconnect
            }
            else
                server ! message
        }
    }
}

This is the Server:

import actors.{Actor,OutputChannel}
import actors.remote.RemoteActor

object Server extends Actor{
    val clients = new collection.mutable.HashSet[OutputChannel[Any]]
    def act{
        loop{
            react{
                case 'Connect =>
                    clients += sender
                case 'Disconnect =>
                    clients -= sender
                case message:String =>
                    for(client <- clients)
                        client ! message
            }
        }
    }

    def main(args:Array[String]){
        start
        RemoteActor.alive(9999)
        RemoteActor.register('server,this)
    }
}

Answers


Here's a working version of your source, with pertinent changes commented inline:

import actors.{DaemonActor,remote}
import remote.{RemoteActor,Node}

case class Send(message: String)
case object Disconnect

object SimpleClient{
    val messageHandler = new DaemonActor{

       def act{
          // keep the reference to the proxy inside the client-side actor
          val server = RemoteActor.select(Node("localhost",9999),'server)
          server ! 'Connect
          loop{
             react{
                case message:String =>
                   println("got message: " + message)
                case Send(message) => server ! message
                case Disconnect => { 
                   // disconnect and exit the client-side actor
                   server ! 'Disconnect //'
                   exit
                }
                case _ =>
              }
          }
      }
      start
   }

   def main(args:Array[String]){
      var exit = false
      while(!exit){
         val message = Console.readLine
         if(message == "exit" || message == "quit") {
            exit = true
            // tell the client-side actor to exit
            messageHandler ! Disconnect
         } else {
            messageHandler ! Send(message)
         }
      }
   }
}

[Disclaimer: I'm PO of Akka]

May I suggest taking a look at Akka, which was built with Remote Actors in mind from day 1? www.akka.io


Your question is not really clear enough about what problem you think you are experiencing. Actors do not "connect" to each other (like a socket). You send an actor a message because you have a reference to it (or a proxy, in the case of remote actors).

Having such a reference does not prevent the actor (either actor) from shutting down. If there are no longer any references to an actor and it is not running, there is nothing to stop it being garbage-collected


The Reactor trait defines protected[actors] def exit(): Nothing which the actor can call itself upon reception of a message telling it to do so.

sealed trait Msg
case object Apoptosis extends Msg
// ... more messages


class RRActor extends Reactor[Msg] {
  def act =  loop {
    react {
      // ... Whatever messages the actor handles
      case Apoptosis => this.exit
    }
  }
}

Edit: I have not tested this ever with remote actors.


Need Your Help

Is there anyway to remove an onTouchListener from a view object?

android webview touch listener

I have an on touch listener for a webview, but it has a bad effect on the functionality of the webview, so I am wondering if there is anyway to removed the on touch listener after the initial

How to call getIntent() in adapter class

android listview android-intent

In getView() method I want to call getIntent(). How can I achieve this without starting a new activity. The getView method like this

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.