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);
|
||||
}
|
||||
|
||||
@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()
|
||||
a ! "hallo"
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,23 @@
|
|||
|
||||
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.
|
||||
* 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
|
||||
* requiring runtime-costly manifests.
|
||||
*/
|
||||
trait Channel[-T] {
|
||||
trait Channel[-T] extends japi.Channel[T] {
|
||||
|
||||
/**
|
||||
* Scala API. <p/>
|
||||
* 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
|
||||
|
|
@ -47,32 +90,6 @@ trait Channel[-T] {
|
|||
*/
|
||||
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 =>
|
||||
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
|
||||
``self.channel`` is subtype of ``Channel[Any]``, you may specialise your return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue