make tryTell nice from Scala AND Java
Thanks, Derek Williams, for the good suggestion!
This commit is contained in:
parent
a43418a4c3
commit
2aa86ed37a
5 changed files with 64 additions and 30 deletions
|
|
@ -31,4 +31,10 @@ public class JavaAPI {
|
||||||
});
|
});
|
||||||
assertNotNull(ref);
|
assertNotNull(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test void mustAcceptSingleArgTryTell() {
|
||||||
|
ActorRef ref = Actors.actorOf(JavaAPITestActor.class);
|
||||||
|
ref.tryTell("hallo");
|
||||||
|
ref.tryTell("hallo", ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,16 @@ class ChannelSpec extends WordSpec with MustMatchers {
|
||||||
}).start()
|
}).start()
|
||||||
a ! "hallo"
|
a ! "hallo"
|
||||||
s must be(("hallo", a))
|
s must be(("hallo", a))
|
||||||
|
|
||||||
|
{
|
||||||
|
implicit val actor = a
|
||||||
|
ch tryTell "buh"
|
||||||
|
}
|
||||||
|
s must be(("buh", a))
|
||||||
|
ch.!("world")(a)
|
||||||
|
s must be(("world", a))
|
||||||
|
ch.tryTell("bippy")(a)
|
||||||
|
s must be(("bippy", a))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ abstract class ActorRef extends ActorRefShared with ForwardableChannel with Repl
|
||||||
*
|
*
|
||||||
* If you would rather have an exception, check the <code>reply(..)</code> version.
|
* If you would rather have an exception, check the <code>reply(..)</code> version.
|
||||||
*/
|
*/
|
||||||
def tryReply(message: Any): Boolean = channel.tryTell(message, this)
|
def tryReply(message: Any): Boolean = channel.tryTell(message)(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the dispatcher for this actor. Needs to be invoked before the actor is started.
|
* Sets the dispatcher for this actor. Needs to be invoked before the actor is started.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,23 @@
|
||||||
|
|
||||||
package akka.actor
|
package akka.actor
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This package is just used to hide the tryTell method from the Scala parts:
|
||||||
|
* it will be public to javac's eyes by virtue of §5.2 of the SLS.
|
||||||
|
*/
|
||||||
|
package japi {
|
||||||
|
trait Channel[-T] { self: akka.actor.Channel[T] ⇒
|
||||||
|
private[japi] def tryTell(msg: T): Boolean = {
|
||||||
|
try {
|
||||||
|
self.!(msg)(NullChannel)
|
||||||
|
true
|
||||||
|
} catch {
|
||||||
|
case _: Exception ⇒ false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstraction for unification of sender and senderFuture for later reply.
|
* Abstraction for unification of sender and senderFuture for later reply.
|
||||||
* Can be stored away and used at a later point in time.
|
* Can be stored away and used at a later point in time.
|
||||||
|
|
@ -12,13 +29,39 @@ package akka.actor
|
||||||
* untyped, as there is no way to utilize its real static type without
|
* untyped, as there is no way to utilize its real static type without
|
||||||
* requiring runtime-costly manifests.
|
* requiring runtime-costly manifests.
|
||||||
*/
|
*/
|
||||||
trait Channel[-T] {
|
trait Channel[-T] extends japi.Channel[T] {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scala API. <p/>
|
* Scala API. <p/>
|
||||||
* Sends the specified message to the channel.
|
* Sends the specified message to the channel.
|
||||||
*/
|
*/
|
||||||
def !(msg: T)(implicit channel: UntypedChannel): Unit
|
def !(msg: T)(implicit sender: UntypedChannel): Unit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scala and Java API. <p/>
|
||||||
|
* Try to send the specified message to the channel, i.e. fire-and-forget
|
||||||
|
* semantics, including the sender reference if possible (not supported on
|
||||||
|
* all channels).<p/>
|
||||||
|
* From Java:
|
||||||
|
* <pre>
|
||||||
|
* actor.tryTell(message);
|
||||||
|
* actor.tryTell(message, context);
|
||||||
|
* </pre>
|
||||||
|
* <p/>
|
||||||
|
* From Scala:
|
||||||
|
* <pre>
|
||||||
|
* actor tryTell message
|
||||||
|
* actor.tryTell(message)(sender)
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
def tryTell(msg: T)(implicit sender: UntypedChannel): Boolean = {
|
||||||
|
try {
|
||||||
|
this.!(msg)(sender)
|
||||||
|
true
|
||||||
|
} catch {
|
||||||
|
case _: Exception ⇒ false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to send an exception. Not all channel types support this, one notable
|
* Try to send an exception. Not all channel types support this, one notable
|
||||||
|
|
@ -47,32 +90,6 @@ trait Channel[-T] {
|
||||||
*/
|
*/
|
||||||
def tell(msg: T, sender: UntypedChannel): Unit = this.!(msg)(sender)
|
def tell(msg: T, sender: UntypedChannel): Unit = this.!(msg)(sender)
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to send the specified message to the channel, i.e. fire-and-forget semantics.<p/>
|
|
||||||
* <pre>
|
|
||||||
* channel.tell(message);
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
def tryTell(msg: T): Boolean = this.tryTell(msg, NullChannel)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Java API. <p/>
|
|
||||||
* Try to send the specified message to the channel, i.e. fire-and-forget
|
|
||||||
* semantics, including the sender reference if possible (not supported on
|
|
||||||
* all channels).<p/>
|
|
||||||
* <pre>
|
|
||||||
* actor.tell(message, context);
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
def tryTell(msg: T, sender: UntypedChannel): Boolean = {
|
|
||||||
try {
|
|
||||||
this.!(msg)(sender)
|
|
||||||
true
|
|
||||||
} catch {
|
|
||||||
case _: Exception ⇒ false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,8 @@ Simply call ``self.channel`` and then you can forward that to others, store it a
|
||||||
|
|
||||||
case request =>
|
case request =>
|
||||||
val result = process(request)
|
val result = process(request)
|
||||||
self.channel ! result
|
self.channel ! result // will throw an exception if there is no sender information
|
||||||
|
self.channel tryTell result // will return Boolean whether reply succeeded
|
||||||
|
|
||||||
The :class:`Channel` trait is contravariant in the expected message type. Since
|
The :class:`Channel` trait is contravariant in the expected message type. Since
|
||||||
``self.channel`` is subtype of ``Channel[Any]``, you may specialise your return
|
``self.channel`` is subtype of ``Channel[Any]``, you may specialise your return
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue