Compositional construction of your functions, mainly.  pipeTo gets the data
to where it needs to be in order to work safely, but you wind up writing a
separate clause in your receive to handle that response, at which point
ask() isn't gaining all that much over simply doing tells back and forth.
Your logic winds up getting sliced-and-diced over a bunch of receive case
clauses.

request(), OTOH, allows you to build more natural code, that *looks* like
programming with Futures, where the response processing can be right there
with the request.  I've found that this approach produces much more
readable code, especially when you get into complex situations.  For
example, you can compose recursive structures, like this example from the
unit tests
<https://github.com/jducoeur/Requester/blob/master/src/test/scala/org/querki/requester/ComprehensionTests.scala#L94-L108>
:

class Exponent extends QTestActor { def doReceive = { case Terms(seed, exp)
=> askDoubler(seed, exp) foreach { result => sender ! result } } def
askDoubler(seed:Int, exp:Int):RequestM[Int] = { if (exp == 1) { RequestM
.successful(seed) } else { doubler.requestFor[Int](seed) flatMap { doubled
=> askDoubler(doubled, exp - 1) } } } }

In this example, askDoubler is essentially folding over a series of
doubling operations, pretty much exactly the way you would do with Futures.
 (Granted, this example is pure-functional, so you could potentially just
ignore the dangers of using ask and Future, but as soon as you interact
with the Actor's state Requester becomes crucial.)  Moreover, it gives you
a nice composable handle, so doReceive() can simply say what to do with the
results of the whole chain of askDoubler operations.  (I wanted a more
complex, impure version of this example in my real code a few days ago,
which is what led to this second release of Requester.)

And of course, since RequestM is strongly typed (like Future), it makes it
much easier to compose complex processes in a strongly-typed way.  I've
caught more than one bug in the IDE simply through that type checking,
because the IDE pointed out that my RequestMs didn't line up properly.

So that's the real advantage, and really what I've been trying to
accomplish: doing Future-style programming while not breaking the Actor
invariants.  I find it much more natural, especially for my higher-level
Actors that are doing lots of interaction with other Actors.  Indeed, it
basically is nothing more than a shell *around* ask + forward, providing a
higher-level abstraction...

On Wed, Jul 29, 2015 at 11:14 AM, Heiko Seeberger <[email protected]> wrote:

> Is Requester offering any benefits over ask in combination with pipeTo?
>
> Thanks
> Heiko
>
> --
>
> *Heiko Seeberger*
> Home: heikoseeberger.de
> Twitter: @hseeberger <https://twitter.com/hseeberger>
> Public key: keybase.io/hseeberger
>
> On 29 Jul 2015, at 16:49, Justin du coeur <[email protected]> wrote:
>
> For those who are interested, I have just cut the second major release of the
> Requester library <https://github.com/jducoeur/Requester>, with many
> improvements over 1.1.
>
>
> *What it is:* Requester introduces request(), which can be thought of as
> the better-behaved big brother to ask().  ask() returns a Future, and is
> therefore quite dangerous to use inside of an Actor, because the Future
> violates the single-threadedness of the Actor, and doesn't preserve sender.
>  request(), by contrast, loops the result of its request back into the
> Actor's mailbox *and* preserves sender across the whole thing.
> Basically, request() works the way you intuitively *expect* ask() to work.
>
> As a result, Requester allows you to safely write completely natural,
> composed, multi-Actor code inside of an Actor, like this:
>
> case GetSpacesStatus(requester) => {
>   for {
>     ActiveThings(nConvs) <- conversations ? GetActiveThings
>     ActiveSessions(nSessions) <- sessions ? GetActiveSessions
>   }
>     sender ! SpaceStatus(spaceId, state.displayName, nConvs, nSessions)
> }
>
> There is a lot more -- Requester is heavily used by Querki
> <https://www.querki.net/help/#What-is-Querki>, and I've been evolving it
> steadily.  At this point, I think it's in good shape for other folks to
> make serious use of it.  I invite y'all to play with it; comments and PRs
> are warmly welcomed.
>
> (And yes, I still need to write up a PR for the Akka documentation, for
> the external contributions section. I hadn't done so before because I
> wasn't happy enough about the state of things, but it seems to be getting
> solid enough now.)
>
>
> *Changes in 2.0*
>
> The most important change is that RequestM (the equivalent of Future -- a
> block of work that will be executed in the Actor's receive loop) is now
> much better-behaved, monadically. By and large, you can treat a RequestM
> like a Future, and it will typically do what you expect.  In particular,
> RequestMs now generally compose correctly, where they previously only
> composed in certain ways.
>
> There is now an implicit conversion from RequestM[T] to Future[T].  This
> makes it easier to use when your Actor is implementing Future-oriented
> functions.  (Which I find comes up in client-server RPC programming.)
>
> The loopback is now caught in unhandled(), so you can usually just mix in
> Requester and start using it.  You only need to explicitly call
> handleRequestResponse under certain special circumstances.
>
> ? is now an alias for request(), intentionally mimicking ask().
>
> --
> >>>>>>>>>> Read the docs: http://akka.io/docs/
> >>>>>>>>>> Check the FAQ:
> http://doc.akka.io/docs/akka/current/additional/faq.html
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> ---
> You received this message because you are subscribed to the Google Groups
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.
>
>
>  --
> >>>>>>>>>> Read the docs: http://akka.io/docs/
> >>>>>>>>>> Check the FAQ:
> http://doc.akka.io/docs/akka/current/additional/faq.html
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> ---
> You received this message because you are subscribed to the Google Groups
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to