This page is no longer maintained — Please continue to the home page at www.scala-lang.org

!? problems in remote actor framework

3 replies
Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
.hmmessage P { margin:0px; padding:0px } body.hmmessage { font-size: 10pt; font-family:Verdana } I'm using the !? operator in remote actors and whilst it seems to work OK (i.e. I get a response), the react loop then doesn't seem to work properly. For example:
    val peer = Node(host, port)    base = actor {      RemoteActor.classLoader = getClass.getClassLoader
      val server = select(peer, id)      val uuid = UUID.randomUUID      // ****      server.!?(2000L, RegisterClient(uuid)) match {        case Some(ack) => println("Client successfully registered: " + ack)        case None =>          severe("Server not responding: " + server)          exit('noserver)      }      // ****      println("Client [%s] entering reaction loop".format(self))
      loop {        react {          case Heartbeat(t) =>            time = t            println("Heartbeat: " + t)

           ... etc

I see the following in the logs:
    Client successfully registered: RegisterClientAck(86e03eab-65d6-417d-9af7-8c8ee5e6e532)    Client [scala.actors.Actor$$anon$1@f5da06] entering reaction loop
And that's it (no heartbeats). When I replace the lines in between // *** with the following...
      server ! RegisterClient(uuid)
I get the following printed out:
    Client [scala.actors.Actor$$anon$1@defa1a] entering reaction loop    Heartbeat: 2009-06-29 15:20:24.965 UTC
    Heartbeat: 2009-06-29 15:20:29.965 UTC    Heartbeat: 2009-06-29 15:20:34.965 UTC
So even though the !? appears to work just fine, my reactions aren't working. In both cases I haven't even re-started the server component, which registers clients as follows:
          case RegisterClient(uuid) =>            clients += (uuid -> sender)            println("Registered new client [%s]; supporting %d clients".format(sender, clients.size))            sender ! RegisterClientAck(uuid) //ACK CONNECTION REQUEST
And heartbeats thus:
            clients foreach  { case (uuid,channel) =>              println("Sending %s to %s".format(notif, channel))              channel ! notif            }

I can see that the server is sending out heartbeats in all cases.
Chris



Upgrade to Internet Explorer 8 Optimised for MSN. Download Now
Philipp Haller
Joined: 2009-01-13,
User offline. Last seen 42 years 45 weeks ago.
Re: !? problems in remote actor framework

christopher marshall wrote:
> I'm using the !? operator in remote actors and whilst it seems to work
> OK (i.e. I get a response), the react loop then doesn't seem to work
> properly. For example:
>
> val peer = Node(host, port)
> base = actor {
> RemoteActor.classLoader = getClass.getClassLoader
> val server = select(peer, id)
> val uuid = UUID.randomUUID
> // ****
> server.!?(2000L, RegisterClient(uuid)) match {
> case Some(ack) => println("Client successfully registered: " + ack)
> case None =>
> severe("Server not responding: " + server)
> exit('noserver)
> }
> // ****
> println("Client [%s] entering reaction loop".format(self))
> loop {
> react {
> case Heartbeat(t) =>
> time = t
> println("Heartbeat: " + t)
>
>
> ... etc
>
>
> I see the following in the logs:
>
> Client successfully registered:
> RegisterClientAck(86e03eab-65d6-417d-9af7-8c8ee5e6e532)
> Client [scala.actors.Actor$$anon$1@f5da06] entering reaction loop
>
> And that's it (no heartbeats). When I replace the lines in between //
> *** with the following...
>
> server ! RegisterClient(uuid)
>
> I get the following printed out:
>
> Client [scala.actors.Actor$$anon$1@defa1a] entering reaction loop
> Heartbeat: 2009-06-29 15:20:24.965 UTC
> Heartbeat: 2009-06-29 15:20:29.965 UTC
> Heartbeat: 2009-06-29 15:20:34.965 UTC
>
> So even though the !? appears to work just fine, my reactions aren't
> working. In both cases I haven't even re-started the server component,
> which registers clients as follows:
>
> case RegisterClient(uuid) =>
> clients += (uuid -> sender)
> println("Registered new client [%s]; supporting %d
> clients".format(sender, clients.size))
> sender ! RegisterClientAck(uuid) //ACK CONNECTION REQUEST

The problem here is that when you use !? then the server gets a
temporary sender reference which is different from the "real" sending
actor (it's a temporary reply channel). However, the client listens on
that temporary channel only once (to receive the reply for !?).

So, to get the proper sender reference (to be registered in the
`clients` map), and you want to use !? you have to pass the sender
explicitly:

server.!?(2000L, RegisterClient(uuid, Actor.self))

Then, the server should register the 2nd parameter of `RegisterClient`
in the `clients` map. The `sender` is then only used to send back the
reply message.

Cheers,
Philipp

Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: !? problems in remote actor framework
.hmmessage P { margin:0px; padding:0px } body.hmmessage { font-size: 10pt; font-family:Verdana } I tried that but this happens (when the client attempts to send the registration message):
java.io.NotSerializableException: scala.actors.Channel at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at scala.actors.remote.JavaSerializer.serialize(JavaSerializer.scala:37)
I'm running Scala 2.7.5 by the way

> Date: Mon, 29 Jun 2009 17:53:29 +0200
> From: philipp.haller@epfl.ch
> To: oxbow_lakes@hotmail.com
> CC: scala-user@listes.epfl.ch
> Subject: Re: [scala-user] !? problems in remote actor framework
>
> christopher marshall wrote:
> > I'm using the !? operator in remote actors and whilst it seems to work
> > OK (i.e. I get a response), the react loop then doesn't seem to work
> > properly. For example:
> >
> > val peer = Node(host, port)
> > base = actor {
> > RemoteActor.classLoader = getClass.getClassLoader
> > val server = select(peer, id)
> > val uuid = UUID.randomUUID
> > // ****
> > server.!?(2000L, RegisterClient(uuid)) match {
> > case Some(ack) => println("Client successfully registered: " + ack)
> > case None =>
> > severe("Server not responding: " + server)
> > exit('noserver)
> > }
> > // ****
> > println("Client [%s] entering reaction loop".format(self))
> > loop {
> > react {
> > case Heartbeat(t) =>
> > time = t
> > println("Heartbeat: " + t)
> >
> >
> > ... etc
> >
> >
> > I see the following in the logs:
> >
> > Client successfully registered:
> > RegisterClientAck(86e03eab-65d6-417d-9af7-8c8ee5e6e532)
> > Client [scala.actors.Actor$$anon$1@f5da06] entering reaction loop
> >
> > And that's it (no heartbeats). When I replace the lines in between //
> > *** with the following...
> >
> > server ! RegisterClient(uuid)
> >
> > I get the following printed out:
> >
> > Client [scala.actors.Actor$$anon$1@defa1a] entering reaction loop
> > Heartbeat: 2009-06-29 15:20:24.965 UTC
> > Heartbeat: 2009-06-29 15:20:29.965 UTC
> > Heartbeat: 2009-06-29 15:20:34.965 UTC
> >
> > So even though the !? appears to work just fine, my reactions aren't
> > working. In both cases I haven't even re-started the server component,
> > which registers clients as follows:
> >
> > case RegisterClient(uuid) =>
> > clients += (uuid -> sender)
> > println("Registered new client [%s]; supporting %d
> > clients".format(sender, clients.size))
> > sender ! RegisterClientAck(uuid) //ACK CONNECTION REQUEST
>
> The problem here is that when you use !? then the server gets a
> temporary sender reference which is different from the "real" sending
> actor (it's a temporary reply channel). However, the client listens on
> that temporary channel only once (to receive the reply for !?).
>
> So, to get the proper sender reference (to be registered in the
> `clients` map), and you want to use !? you have to pass the sender
> explicitly:
>
> server.!?(2000L, RegisterClient(uuid, Actor.self))
>
> Then, the server should register the 2nd parameter of `RegisterClient`
> in the `clients` map. The `sender` is then only used to send back the
> reply message.
>
> Cheers,
> Philipp
>

View your Twitter and Flickr updates from one place - Learn more!
Philipp Haller
Joined: 2009-01-13,
User offline. Last seen 42 years 45 weeks ago.
Re: !? problems in remote actor framework

Ah, yes, I forgot.

Indeed, the only way to get a valid reference to the sending _actor_ to
the server is by using `!` and _not_ supplying `Actor.self` explicitly.
So, the acknowledgment has to be received explicitly, or using an
additional `!?`.

Cheers,
Philipp

christopher marshall wrote:
> I tried that but this happens (when the client attempts to send the
> registration message):
>
> java.io.NotSerializableException: scala.actors.Channel
> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
> at
> java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
> at
> java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
> at
> java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
> at
> java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
> at scala.actors.remote.JavaSerializer.serialize(JavaSerializer.scala:37)
>
> I'm running Scala 2.7.5 by the way
>
>
> > Date: Mon, 29 Jun 2009 17:53:29 +0200
> > From: philipp.haller@epfl.ch
> > To: oxbow_lakes@hotmail.com
> > CC: scala-user@listes.epfl.ch
> > Subject: Re: [scala-user] !? problems in remote actor framework
> >
> > christopher marshall wrote:
> > > I'm using the !? operator in remote actors and whilst it seems to work
> > > OK (i.e. I get a response), the react loop then doesn't seem to work
> > > properly. For example:
> > >
> > > val peer = Node(host, port)
> > > base = actor {
> > > RemoteActor.classLoader = getClass.getClassLoader
> > > val server = select(peer, id)
> > > val uuid = UUID.randomUUID
> > > // ****
> > > server.!?(2000L, RegisterClient(uuid)) match {
> > > case Some(ack) => println("Client successfully registered: " + ack)
> > > case None =>
> > > severe("Server not responding: " + server)
> > > exit('noserver)
> > > }
> > > // ****
> > > println("Client [%s] entering reaction loop".format(self))
> > > loop {
> > > react {
> > > case Heartbeat(t) =>
> > > time = t
> > > println("Heartbeat: " + t)
> > >
> > >
> > > ... etc
> > >
> > >
> > > I see the following in the logs:
> > >
> > > Client successfully registered:
> > > RegisterClientAck(86e03eab-65d6-417d-9af7-8c8ee5e6e532)
> > > Client [scala.actors.Actor$$anon$1@f5da06] entering reaction loop
> > >
> > > And that's it (no heartbeats). When I replace the lines in between //
> > > *** with the following...
> > >
> > > server ! RegisterClient(uuid)
> > >
> > > I get the following printed out:
> > >
> > > Client [scala.actors.Actor$$anon$1@defa1a] entering reaction loop
> > > Heartbeat: 2009-06-29 15:20:24.965 UTC
> > > Heartbeat: 2009-06-29 15:20:29.965 UTC
> > > Heartbeat: 2009-06-29 15:20:34.965 UTC
> > >
> > > So even though the !? appears to work just fine, my reactions aren't
> > > working. In both cases I haven't even re-started the server component,
> > > which registers clients as follows:
> > >
> > > case RegisterClient(uuid) =>
> > > clients += (uuid -> sender)
> > > println("Registered new client [%s]; supporting %d
> > > clients".format(sender, clients.size))
> > > sender ! RegisterClientAck(uuid) //ACK CONNECTION REQUEST
> >
> > The problem here is that when you use !? then the server gets a
> > temporary sender reference which is different from the "real" sending
> > actor (it's a temporary reply channel). However, the client listens on
> > that temporary channel only once (to receive the reply for !?).
> >
> > So, to get the proper sender reference (to be registered in the
> > `clients` map), and you want to use !? you have to pass the sender
> > explicitly:
> >
> > server.!?(2000L, RegisterClient(uuid, Actor.self))
> >
> > Then, the server should register the 2nd parameter of `RegisterClient`
> > in the `clients` map. The `sender` is then only used to send back the
> > reply message.
> >
> > Cheers,
> > Philipp
> >
>
> ------------------------------------------------------------------------
> View your Twitter and Flickr updates from one place - Learn more!
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland