- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
!? problems in remote actor framework
Mon, 2009-06-29, 16:26
.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
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
Mon, 2009-06-29, 17:07
#2
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!
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!
Mon, 2009-06-29, 17:37
#3
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!
>
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