Idiomatic Akka (! / tell) versus Non-blocking Akka Futures (? / ask)

1,747 views
Skip to first unread message

Nikolay Botev

unread,
Dec 2, 2011, 4:07:46 PM12/2/11
to Akka User List
Hi,

In response to Jonas' tweet yesterday http://twitter.com/#!/jboner/status/142521048305381376
:

"Futures are there as a convenience and if you use the Future non-
blocking API it is as good as !"

I would like to bring forward an important difference between the
behavior of ! and the Future non-blocking API. I think the above
statement can be misleading.

Let's take a look at a very simple example of 2 actors, a service
performing some computation and sending back the result to a client:


class ServiceActor extends Actor {
def receive = { case x: Int =>
log("Service processing " + x)
sender ! (x * x)
}
}

class ClientActor extends Actor {
def receive = {
case serviceProvider: ActorRef => serviceProvider ! 42
case response: Int => log("Client got back " + response)
}
}


In the above examples, actors only use one-way fire-and-forget message
passing via ! (tell).

Based on Jonas' statement, I would expect that I can rewrite the
ClientActor to use ? (ask) and register a non-blocking listener on the
Future to get the same result as follows:


class ClientActor extends Actor {
def receive = {
case serviceProvider: ActorRef => serviceProvider ? 42 onResult
{
case response: Int => log("Client got back " + response)
}
}
}


In this simple example, the result *is* the same and everything works.
There is one very important difference, however. In the case of tell,
the response is processed from within the client actor's thread of
control, whereas in the case of ask, the response is handled in the
service actor's thread of control (or in a temporary actor's thread of
control in Akka 2.0).

This is highlighted by the log method, which simply prints the current
thread's name followed by the message it receives. When running the
above examples with the service and client actors pinned to their own
threads, we get:

In the case of tell:

[service-16] Service processing 42
[client-18] Client got back 1764

In the case of ask:

[service-16] Service processing 42
[DefaultDispatcher-20] Client got back 1764

Note that in the case of ask, the response is handled independently of
the client actor's thread. This is a very important distinction. It
means that while in the case of tell I can safely access the client
actor's state, this is no longer the case once I transform my code
from using tell to using ask+non-blocking futures.

This can be confusing because the code for handling the response in
both cases resides in the Client actor's class, and has full access to
the Client actor's state. In effect this means that it is very easy to
violate the actor model (no shared state) when using ask+onResult if
one does not understand how the Akka Future non-blocking API works.

I bring this issue up here, because I have not found this difference
in semantics clearly explained or discussed on the akka documentation
(neither in 1.x or 2.0), and especially because I worry that Jonas'
tweet can be easily misinterpreted to mean that ask+nonblocking future
api is semantically equivalent to tell, when it is in fact not.

When using ask, it is NOT safe to access the current actor's state
from the closures that are passed to the resulting future to handle
the result.

-Nikolay

Jonas Bonér

unread,
Dec 2, 2011, 4:24:30 PM12/2/11
to akka...@googlegroups.com
On Fri, Dec 2, 2011 at 10:07 PM, Nikolay Botev <bono...@gmail.com> wrote:
> Hi,
>
> In response to Jonas' tweet yesterday http://twitter.com/#!/jboner/status/142521048305381376
> :
>
> "Futures are there as a convenience and if you use the Future non-
> blocking API it is as good as !"
>
> I would like to bring forward an important difference between the
> behavior of ! and the Future non-blocking API. I think the above
> statement can be misleading.
>

It is misleading since it is taken out of context. The context was
that a guy on twitter stated that Akka blocks threads in the
dispatcher and I tried to explain that that is not the case (not even
take locks) and that you can be sure that is not the case for either
tell or ask.

However in terms of semantics they are as you highlight below very
different. We have discussed this quite a lot the last months,
including the problem that the callbacks your register in the
Future.onComplete can close over state that is concurrently accessed
in another thread. We have discussed creating compiler plugins to
detect this and yield a warning. But it is still an unsolved problem.
All help is appreciated.

You are totally right that this needs to be explained in <blink></blink> tags.

> --
> You received this message because you are subscribed to the Google Groups "Akka User List" group.
> To post to this group, send email to akka...@googlegroups.com.
> To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.
>

--
Jonas Bonér
CTO
Typesafe - Enterprise-Grade Scala from the Experts
Phone: +46 733 777 123
Twitter: @jboner

Nikolay Botev

unread,
Dec 3, 2011, 12:53:53 AM12/3/11
to Akka User List
Hi,

Thanks for the prompt reply.

>
> It is misleading since it is taken out of context. The context was
> that a guy on twitter stated that Akka blocks threads in the
> dispatcher and I tried to explain that that is not the case (not even
> take locks) and that you can be sure that is not the case for either
> tell or ask.

My bad. I should have known better than to take things out of
context :)

>
> However in terms of semantics they are as you highlight below very
> different. We have discussed this quite a lot the last months,
> including the problem that the callbacks your register in the
> Future.onComplete can close over state that is concurrently accessed
> in another thread. We have discussed creating compiler plugins to
> detect this and yield a warning. But it is still an unsolved problem.
> All help is appreciated.
>

Have you guys considered the pros and cons of Mark Miller's approach
to this problem in his E programming language?

Thanks,
-Nikolay

Jonas Bonér

unread,
Dec 3, 2011, 4:59:23 AM12/3/11
to akka...@googlegroups.com
On Sat, Dec 3, 2011 at 6:53 AM, Nikolay Botev <bono...@gmail.com> wrote:
> Hi,
>
> Thanks for the prompt reply.
>
>>
>> It is misleading since it is taken out of context. The context was
>> that a guy on twitter stated that Akka blocks threads in the
>> dispatcher and I tried to explain that that is not the case (not even
>> take locks) and that you can be sure that is not the case for either
>> tell or ask.
>
> My bad. I should have known better than to take things out of
> context :)
>

No worries. I should have been more clear and it is an important issue
you are raising.

>>
>> However in terms of semantics they are as you highlight below very
>> different. We have discussed this quite a lot the last months,
>> including the problem that the callbacks your register in the
>> Future.onComplete can close over state that is concurrently accessed
>> in another thread. We have discussed creating compiler plugins to
>> detect this and yield a warning. But it is still an unsolved problem.
>> All help is appreciated.
>>
>
> Have you guys considered the pros and cons of Mark Miller's approach
> to this problem in his E programming language?

I looked at E some years ago, I know about his capabilities approach
and have considered it for Akka earlier, but don't remember enough to
understand what you ar referring to. Could you fill me in?

Speaking about E capabilities I think it could actually now, in Akka
2.0 with its AkkaApplication and enforced tree of actors, be more
natural to plug in. Need to think more about that.

Thanks for the very constructive criticism.

/Jonas

>
> Thanks,

rkuhn

unread,
Dec 3, 2011, 5:53:42 AM12/3/11
to akka...@googlegroups.com

Minor correction: I renamed it to ActorSystem a few days ago ;-) (for those who would like to see what that is on the master branch; some reference/primer will be forthcoming shortly, because it is probably difficult to distill the intent from the code in this case)
 

Thanks for the very constructive criticism.


+1, especially if it may help one day in avoiding these closure-related pitfalls.
 
Regards,

Roland

Debasish Ghosh

unread,
Dec 3, 2011, 6:23:33 AM12/3/11
to akka...@googlegroups.com
Very useful thread. Will be good to have the closure related pitfalls documented somewhere in Akka documentation along with some of the best practices with Akka 1.2+ and 2.0 series.
Debasish Ghosh
http://manning.com/ghosh

Twttr: @debasishg
Blog: http://debasishg.blogspot.com
Code: http://github.com/debasishg

rkuhn

unread,
Dec 3, 2011, 9:55:17 AM12/3/11
to akka...@googlegroups.com, dgh...@acm.org
I created a ticket for collecting these things: https://www.assembla.com/spaces/akka/tickets/1427

Most of it is already documented, but that is scattered around all the docs. My idea would be to have a trouble-shooting guide which suggests patterns/anti-patterns. Feel free to update the ticket with whatever else you think should go in this category.

Jonas Bonér

unread,
Dec 3, 2011, 11:20:04 AM12/3/11
to akka...@googlegroups.com, dgh...@acm.org
Good initiative.

> To view this discussion on the web visit
> https://groups.google.com/d/msg/akka-user/-/sDtayngFKMwJ.

Nikolay Botev

unread,
Dec 9, 2011, 3:36:10 AM12/9/11
to akka...@googlegroups.com
Hi,

On Sat, Dec 3, 2011 at 1:59 AM, Jonas Bonér <jo...@jonasboner.com> wrote:

I looked at E some years ago, I know about his capabilities approach
and have considered it for Akka earlier, but don't remember enough to
understand what you ar referring to. Could you fill me in?


I am referring to E futures (Promises in E's terminology), which support registering a listener for the result via a when { ... } catch { ... } statement, very similar to  onResult and onException in Akka futures. In E, however, the onResult/onException blocks are evaluated in the context of the actor (vat in E's terminology), which executed the when-catch statement. To me this is the one-and-only Right Way to integrate futures with actors, but I am biased. What do you guys think?

-Nikolay


√iktor Ҡlang

unread,
Dec 9, 2011, 3:52:57 AM12/9/11
to akka...@googlegroups.com

Can I have this dish served with some argument-sauce? :-)

Cheers,

 

-Nikolay


--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--
Viktor Klang

Akka Tech Lead
Typesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang

Martin Grigorov

unread,
Dec 9, 2011, 7:46:28 AM12/9/11
to akka...@googlegroups.com
2011/12/9 √iktor Ҡlang <viktor...@gmail.com>:

>
>
> On Fri, Dec 9, 2011 at 9:36 AM, Nikolay Botev <bono...@gmail.com> wrote:
>>
>> Hi,
>>
>> On Sat, Dec 3, 2011 at 1:59 AM, Jonas Bonér <jo...@jonasboner.com> wrote:
>>>
>>>
>>> I looked at E some years ago, I know about his capabilities approach
>>> and have considered it for Akka earlier, but don't remember enough to
>>> understand what you ar referring to. Could you fill me in?
>>>
>>
>> I am referring to E futures (Promises in E's terminology), which support
>> registering a listener for the result via a when { ... } catch { ... }
>> statement, very similar to  onResult and onException in Akka futures. In E,
>> however, the onResult/onException blocks are evaluated in the context of the
>> actor (vat in E's terminology), which executed the when-catch statement.
>
>
>
>
>>
>> To me this is the one-and-only Right Way to integrate futures with actors,
>> but I am biased. What do you guys think?
>
>
> Can I have this dish served with some argument-sauce? :-)

It will be even better if there is a way to set the context, as in
JavaScript with Function.prototype.bind or Function.prototype.apply's
first argument.

rkuhn

unread,
Dec 9, 2011, 8:36:57 AM12/9/11
to akka...@googlegroups.com
What you mean is basically that all onComplete work should just send the callbacks back to their actors as messages and have them automatically executed through the normal mailbox run.

Your suggestion:

class MyActor extends Actor {
  var someState = _
  def receive = {
    case req => Future { doIt(req) } onComplete (f => someState = f.get)
  }
}

Currently supported solution:

class MyActor extends Actor {
  var someState = _
  def receive = {
    case f: Future[_] => someState = f.get
    case req => Future { doIt(req) } onComplete (self ! _)
  }
}

(I took some liberty in demonstrating the principle, you may want to send a different message instead)

In 2.0 we will have “pipeTo(ref: ActorRef”) available on futures to make this even easier. WDYT?

Regards,

Roland
 
-Nikolay


Nikolay Botev

unread,
Dec 11, 2011, 12:08:14 AM12/11/11
to akka...@googlegroups.com
Hi Roland,

On Fri, Dec 9, 2011 at 5:36 AM, rkuhn <goo...@rkuhn.info> wrote:
What you mean is basically that all onComplete work should just send the callbacks back to their actors as messages and have them automatically executed through the normal mailbox run.

This is precisely correct. Thanks for clarifying the language.
 

Your suggestion:

class MyActor extends Actor {
  var someState = _
  def receive = {
    case req => Future { doIt(req) } onComplete (f => someState = f.get)
  }
}

Currently supported solution:

class MyActor extends Actor {
  var someState = _
  def receive = {
    case f: Future[_] => someState = f.get
    case req => Future { doIt(req) } onComplete (self ! _)
  }
}

(I took some liberty in demonstrating the principle, you may want to send a different message instead)

In 2.0 we will have “pipeTo(ref: ActorRef”) available on futures to make this even easier. WDYT?

I think pipeTo self is a decent workaround.

However, as described in my previous post, I find that the style of E has the advantage that it is simpler and it preserves control flow.

Cheers,
-Nikolay

Nikolay Botev

unread,
Dec 10, 2011, 11:29:16 PM12/10/11
to akka...@googlegroups.com
Hi,

2011/12/9 √iktor Ҡlang <viktor...@gmail.com>

 
To me this is the one-and-only Right Way to integrate futures with actors, but I am biased. What do you guys think?

Can I have this dish served with some argument-sauce? :-)

Sure. Here it goes:

I start with some blocking code in a top-level { case => ...  } block, say:

case SomeMessage =>
  //
  // do some work ...
  //
  val result = someActor ? aMessage
  val x = result.get
  //
  // ...
  // do lots of fun stuff with the result ...
  // ...
  //

I want to translate this code to be non-blocking (I assume we agree on the need to do this) while fully preserving the behavior of my code. With E semantics. the transformation is simple and involves only wrapping the fun stuff in a closure and registering it with the future (let's not worry about exceptions for now, for the sake of simplicity):

case SomeMessage =>
  //
  // do work ...
  //
  val result = someActor ? aMessage
  result onResult { case x =>
    //
    // ...
    // do lots of fun stuff with the result ...
    // ...
    //
  }

Mark Miller calls this "reifying control flow."

With present Akka semantics, the above is problematic. To achieve the same effect, I have to use "pipeTo self", or "self !" to forward the result as a top-level message to myself. This breaks up control flow because:
  * the "fun stuff" code will have a tendency over time to move farther and farther away from the code which precedes it in the original control flow
  * the sender of a top-level message could be something other than this specific onResult handler.

Of course the above assumes that the fun stuff cannot be impacted by other messages arriving to me before the result. In my humble experience, many times this is not the case, and if your fun stuff *can* get affected by the processing of other messages, then you must either block or manually buffer [subsequent messages], regardless of the future onResult semantics.

When I talk about actors to people with a C background and event-based programming experience, one of the first concerns that is raised is about control-flow - there is some persistent view that event-based programming breaks up the control flow of your program and makes things hard to read/maintain/debug. I believe Mark Miller's approach helps maintain the control-flow of your program with some overhead of the closure decorations around subsequent code.

To sum up, the difference between E and present Akka semantics is in the default behavior:
* In the style of E, pipeTo is the defulat behavior (however, the message is trapped and never visible to the user-supplied receive), I can always spawn { } explicitly if I want to process my future result concurrently in a temporary actor.
* In the present Akka style, temporary actor is the default, and I must pipeTo if I want to explicitly. The piped message comes as a top-level message, and it is difficult to ensure the code will only execute in response to the future resolution (someone else might send me a message of the same type directly).

IMO, the E style is more intuitive, and holds much less surprises for new developers (no implicit creation of temporary actors, no need for compiler plugins to stop people from shooting self in foot), and also gives a pragmatic (not perfect!) answer to the concerns about event-based programming and control flow, and allows for more maintainable code.

I am introducing actors for a new project at work. I find it a nuisance and distraction to have to explain to people that they must pipeTo every time. Of course, I could dodge the issue and preach idiomatic akka, but I believe I could do much better if I had E-style futures, especially in the face of complaints that idiomatic actors break up control flow and lead to unreadable spaghetti code (complaints I have to admit I agree with and therefore cannot discount). In fact, I already wrote an initial prototype of typed actors with E-style futures tightly integrated. The prototype can work on top of idiomatic akka or scala actors, or any other implementation of actors with bang (!). The prototype is far from a complete implementation, but hopefully I will be allowed to post it on github soon.

-Nikolay

Patrik Nordwall

unread,
Dec 11, 2011, 4:38:54 AM12/11/11
to akka...@googlegroups.com
Instead of using ? followed by pipeTo self  you can use ! and the reply from the target actor will be a message received as usual in the original sender.

Note that you can also specify another (explicit) sender in ! to use a temporary actor (or whatever) to handle the replies.

--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--

Patrik Nordwall

Typesafe - Enterprise-Grade Scala from the Experts

Twitter: @patriknw


rkuhn

unread,
Dec 11, 2011, 4:41:25 AM12/11/11
to akka...@googlegroups.com
Agreed on all points.
 
When I talk about actors to people with a C background and event-based programming experience, one of the first concerns that is raised is about control-flow - there is some persistent view that event-based programming breaks up the control flow of your program and makes things hard to read/maintain/debug. I believe Mark Miller's approach helps maintain the control-flow of your program with some overhead of the closure decorations around subsequent code.

To sum up, the difference between E and present Akka semantics is in the default behavior:
* In the style of E, pipeTo is the defulat behavior (however, the message is trapped and never visible to the user-supplied receive), I can always spawn { } explicitly if I want to process my future result concurrently in a temporary actor.
* In the present Akka style, temporary actor is the default, and I must pipeTo if I want to explicitly. The piped message comes as a top-level message, and it is difficult to ensure the code will only execute in response to the future resolution (someone else might send me a message of the same type directly).

Yes, agreed. One thing which you do not mention, though, is that the present Akka style shows you at a glance which messages an actor handles, as there is only one entry point. As soon as you introduce additional syntax for handling messages, which may be widely scattered around, you might have difficulty finding performance bottlenecks; this is not meant to say that I think that style unsuitable, just something to keep in mind.
 
IMO, the E style is more intuitive, and holds much less surprises for new developers (no implicit creation of temporary actors, no need for compiler plugins to stop people from shooting self in foot), and also gives a pragmatic (not perfect!) answer to the concerns about event-based programming and control flow, and allows for more maintainable code.

Yes, true.
 
I am introducing actors for a new project at work. I find it a nuisance and distraction to have to explain to people that they must pipeTo every time. Of course, I could dodge the issue and preach idiomatic akka, but I believe I could do much better if I had E-style futures, especially in the face of complaints that idiomatic actors break up control flow and lead to unreadable spaghetti code (complaints I have to admit I agree with and therefore cannot discount). In fact, I already wrote an initial prototype of typed actors with E-style futures tightly integrated. The prototype can work on top of idiomatic akka or scala actors, or any other implementation of actors with bang (!). The prototype is far from a complete implementation, but hopefully I will be allowed to post it on github soon.

I would be very interested in seeing an implementation of this idea: with Akka we have a very robust platform on which to build more “fancy” stuff, and as you probably found while writing your prototype it is readily extensible. I could imagine adding such a contribution as a trait to be mixed into Actor which would give you this behavior, should be doable by overriding receive() for handling the message and wrapping Future to carry along the sender reference, which you could capture e.g. by pimping a new ?? onto ActorRef or some such.

Depending on how it works out, we could then also weave it more tightly into Actor, ActorRef and Future, but given that there are valid use cases for onComplete & friends without actors which should retain their semantics, I would prefer to have separate syntax for this feature.

Regards,

Roland

rkuhn

unread,
Dec 11, 2011, 4:55:53 AM12/11/11
to akka...@googlegroups.com
The thing is that he wants to write the code for handling the reply exactly in place, i.e. where the send happens, so he must store a closure with that request somewhere.

So, first thought here: be careful not to create memory leaks!

Second thought: what about the following syntax?

target <= msg then {
  case x => ...
}

No need to involve Future at all here, that is just an implementation detail. The “<=” and “then” are just some colors on a bike-shed.

Regards,

Roland

√iktor Ҡlang

unread,
Dec 11, 2011, 7:42:26 AM12/11/11
to akka...@googlegroups.com
Hey guys,

We shouldn't conflate different things here.

Actors have their behavior defined inside of them, and they have potentially mutable state. Closing over that mutable state is a big no-no since the Actor-instance can be replaced as a response to an internal failure at any point in time.

If you want to supply behavior externally, you should definitely use Futures and asynchronous composition, you can even use our Dataflow API to make it a bit more strict-looking: http://akka.io/docs/akka/1.3-RC3/scala/dataflow.html

Normally, if you want to do what you want to do, you'd create a new actor to continue the workflow.

Cheers,


To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/SvQ6hDyn_9cJ.

To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--
Viktor Klang

Akka Tech Lead
Typesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang

rkuhn

unread,
Dec 11, 2011, 9:59:33 AM12/11/11
to akka...@googlegroups.com


Am Sonntag, 11. Dezember 2011 13:42:26 UTC+1 schrieb Viktor Klang:
Hey guys,

We shouldn't conflate different things here.

Actors have their behavior defined inside of them, and they have potentially mutable state. Closing over that mutable state is a big no-no since the Actor-instance can be replaced as a response to an internal failure at any point in time.

Damn, this keeps coming back ;-) But IF you were to never restart the actor, i.e. only use Resume or Stop actions, then this approach would work, even though you close over the internal mutable state.
 
If you want to supply behavior externally, you should definitely use Futures and asynchronous composition, you can even use our Dataflow API to make it a bit more strict-looking: http://akka.io/docs/akka/1.3-RC3/scala/dataflow.html

Normally, if you want to do what you want to do, you'd create a new actor to continue the workflow.

... which has worse problems, since it also (unintentionally) closes over this actor’s mutable state, plus it will be executed in parallel, so you have data races in addition.

The problem really is this greediness of Scala closures, where you cannot tell them to close-by-value. Since we cannot fix that (at least not short-term, probably not even medium-term), we should aim to make it easiest to do the non-stupid thing.
 
Up to now I have not seen anything which fits perfectly, and there may well not be a silver bullet for this one.

Regards,

Roland

Cheers,


On Sun, Dec 11, 2011 at 10:55 AM, rkuhn <goo...@rkuhn.info> wrote:
The thing is that he wants to write the code for handling the reply exactly in place, i.e. where the send happens, so he must store a closure with that request somewhere.

So, first thought here: be careful not to create memory leaks!

Second thought: what about the following syntax?

target <= msg then {
  case x => ...
}

No need to involve Future at all here, that is just an implementation detail. The “<=” and “then” are just some colors on a bike-shed.

Regards,

Roland

Am Sonntag, 11. Dezember 2011 10:38:54 UTC+1 schrieb Patrik Nordwall:
Instead of using ? followed by pipeTo self  you can use ! and the reply from the target actor will be a message received as usual in the original sender.

Note that you can also specify another (explicit) sender in ! to use a temporary actor (or whatever) to handle the replies.

On Sun, Dec 11, 2011 at 5:29 AM, Nikolay Botev <bon...@gmail.com> wrote:
Hi,


2011/12/9 √iktor Ҡlang <vikt...@gmail.com>
To post to this group, send email to akk...@googlegroups.com.
To unsubscribe from this group, send email to akka-u...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--

Patrik Nordwall
Typesafe - Enterprise-Grade Scala from the Experts
Twitter: @patriknw


--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/SvQ6hDyn_9cJ.

To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.

Derek Williams

unread,
Dec 11, 2011, 11:35:21 AM12/11/11
to akka...@googlegroups.com
Personally, I've begun trying to put any closure that will be executing asynchronously inside a companion object, forcing me to explicitly pass the values I want. Helps prevent little mistakes.

--
Derek Williams

√iktor Ҡlang

unread,
Dec 11, 2011, 12:21:30 PM12/11/11
to akka...@googlegroups.com
On Sun, Dec 11, 2011 at 5:35 PM, Derek Williams <de...@fyrie.net> wrote:
Personally, I've begun trying to put any closure that will be executing asynchronously inside a companion object, forcing me to explicitly pass the values I want. Helps prevent little mistakes.

That's a good tip. It's essentially a closure-constructor.
 

--
Derek Williams

--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.

Nikolay Botev

unread,
Dec 11, 2011, 3:29:05 PM12/11/11
to akka...@googlegroups.com
Victor,

2011/12/11 √iktor Ҡlang <viktor...@gmail.com>

Actors have their behavior defined inside of them, and they have potentially mutable state. Closing over that mutable state is a big no-no since the Actor-instance can be replaced as a response to an internal failure at any point in time.

Thanks, I was not aware of this issue. This is why I was reluctant to begin laying out detailed arguments for E-style concurrency. E is quite different from Akka and looking at Akka through E-lenses, I was sure I would be missing something in the big picture.

E does follow the general idea of let-it-crash with automatic restart though, with the vat (actor) being the unit of failure, similar to Akka/Erlang. In E, the vat also includes the heap and the mailbox, so any closures you had registered as listeners to promises would be thrown away when the vat crashes.

In Akka, when the Actor-instance is replaced do the current mailbox contents also go away?

Thanks,
-Nikolay

Nikolay Botev

unread,
Dec 11, 2011, 3:34:58 PM12/11/11
to akka...@googlegroups.com
Hi Roland,

On Sun, Dec 11, 2011 at 6:59 AM, rkuhn <goo...@rkuhn.info> wrote:
 
Up to now I have not seen anything which fits perfectly, and there may well not be a silver bullet for this one.

I have a hard time distilling the fundamental issues of fitting E-style futures with Akka out of the general discussion in this thread. Can you help me by pointing out what you see as the fundamental problems with integrating the E approach?

Thanks,
-Nikolay

Nikolay Botev

unread,
Dec 11, 2011, 3:47:06 PM12/11/11
to akka...@googlegroups.com
Roland,

On Sun, Dec 11, 2011 at 1:55 AM, rkuhn <goo...@rkuhn.info> wrote:
The thing is that he wants to write the code for handling the reply exactly in place, i.e. where the send happens, so he must store a closure with that request somewhere.

So, first thought here: be careful not to create memory leaks!

That I see as mostly a framework concern. Tight integration of Promise and Resolver into the framework is crucial to this approach.


Second thought: what about the following syntax?

target <= msg then {
  case x => ...
}

No need to involve Future at all here, that is just an implementation detail. The “<=” and “then” are just some colors on a bike-shed.

Agreed. The first question that I have is: how does this look for typed actors?

Thanks,
-Nikolay

Nikolay Botev

unread,
Dec 11, 2011, 3:52:18 PM12/11/11
to akka...@googlegroups.com
Hi Martin,


On Fri, Dec 9, 2011 at 4:46 AM, Martin Grigorov <martin....@gmail.com> wrote:

It will be even better if there is a way to set the context, as in
JavaScript with Function.prototype.bind or Function.prototype.apply's
first argument.

This is an interesting comment, but I would rather not go there. Scala is very different from Javascript.

Cheers,
-Nikolay

Nikolay Botev

unread,
Dec 11, 2011, 3:55:12 PM12/11/11
to akka...@googlegroups.com
Hi Patrik,

On Sun, Dec 11, 2011 at 1:38 AM, Patrik Nordwall <patrik....@gmail.com> wrote:
Instead of using ? followed by pipeTo self  you can use ! and the reply from the target actor will be a message received as usual in the original sender.

Note that you can also specify another (explicit) sender in ! to use a temporary actor (or whatever) to handle the replies.

 
Thanks for the suggestion. You are right these are plausible alternatives.

-Nikolay

Nikolay Botev

unread,
Dec 11, 2011, 4:39:50 PM12/11/11
to akka...@googlegroups.com
Hi Roland

On Sun, Dec 11, 2011 at 1:41 AM, rkuhn <goo...@rkuhn.info> wrote:
 
When I talk about actors to people with a C background and event-based programming experience, one of the first concerns that is raised is about control-flow - there is some persistent view that event-based programming breaks up the control flow of your program and makes things hard to read/maintain/debug. I believe Mark Miller's approach helps maintain the control-flow of your program with some overhead of the closure decorations around subsequent code.

To sum up, the difference between E and present Akka semantics is in the default behavior:
* In the style of E, pipeTo is the defulat behavior (however, the message is trapped and never visible to the user-supplied receive), I can always spawn { } explicitly if I want to process my future result concurrently in a temporary actor.
* In the present Akka style, temporary actor is the default, and I must pipeTo if I want to explicitly. The piped message comes as a top-level message, and it is difficult to ensure the code will only execute in response to the future resolution (someone else might send me a message of the same type directly).

Yes, agreed. One thing which you do not mention, though, is that the present Akka style shows you at a glance which messages an actor handles, as there is only one entry point. As soon as you introduce additional syntax for handling messages, which may be widely scattered around, you might have difficulty finding performance bottlenecks; this is not meant to say that I think that style unsuitable, just something to keep in mind.

You are right. One thing I never mentioned is that in E there is no single entry point to an actor (vat). All non-value objects (including closures) are proxied when exposed to the outside world and act as entry-points for the actor. Of course, this is only possible in a dynamically strong-typed environment where my method returns Int but the proxy can return Promise[Int].

Fitting something similar into Akka does mean that we get these special objects (Futures) that can magically act as additional entry points to the actor. Still, I am convinced this is the best way to fit non-blocking futures with actors.

This approach gives actors+non-blocking futures a very definitive edge over existing non-blocking APIs which take an listener object and invoke it on some indeterminate thread in the future, and you need to worry about synchronization over your shared state.
 
I would be very interested in seeing an implementation of this idea: with Akka we have a very robust platform on which to build more “fancy” stuff, and as you probably found while writing your prototype it is readily extensible.

At this point my prototype is not coupled to a particular actors implementation, since it only relies on !. In order to fully support Akka, including supervisors and cross-JVM transparency, it will have to become tightly coupled.

So far, I have to applaud you guys for eliminating global state in Akka 2.0. Thank you!
 
I could imagine adding such a contribution as a trait to be mixed into Actor which would give you this behavior, should be doable by overriding receive() for handling the message and wrapping Future to carry along the sender reference, which you could capture e.g. by pimping a new ?? onto ActorRef or some such.

I also would like to applaud you for simplifying the API and getting rid of !!, !!, !? etc in Akka 2.0. I would not dare ask for any new multi-letter operators.
 
Depending on how it works out, we could then also weave it more tightly into Actor, ActorRef and Future, but given that there are valid use cases for onComplete & friends without actors which should retain their semantics, I would prefer to have separate syntax for this feature.

Agreed. The abundance of features in Akka, such as STM, Dataflow, and standalone pipelining Futures, makes adopting new semantics for futures when used with actors a challenging problem.

Cheers,
-Nikolay

rkuhn

unread,
Dec 12, 2011, 12:04:53 PM12/12/11
to akka...@googlegroups.com


Am Sonntag, 11. Dezember 2011 22:39:50 UTC+1 schrieb Nikolay Botev:
Hi Roland

On Sun, Dec 11, 2011 at 1:41 AM, rkuhn <goo...@rkuhn.info> wrote:
 
When I talk about actors to people with a C background and event-based programming experience, one of the first concerns that is raised is about control-flow - there is some persistent view that event-based programming breaks up the control flow of your program and makes things hard to read/maintain/debug. I believe Mark Miller's approach helps maintain the control-flow of your program with some overhead of the closure decorations around subsequent code.

To sum up, the difference between E and present Akka semantics is in the default behavior:
* In the style of E, pipeTo is the defulat behavior (however, the message is trapped and never visible to the user-supplied receive), I can always spawn { } explicitly if I want to process my future result concurrently in a temporary actor.
* In the present Akka style, temporary actor is the default, and I must pipeTo if I want to explicitly. The piped message comes as a top-level message, and it is difficult to ensure the code will only execute in response to the future resolution (someone else might send me a message of the same type directly).

Yes, agreed. One thing which you do not mention, though, is that the present Akka style shows you at a glance which messages an actor handles, as there is only one entry point. As soon as you introduce additional syntax for handling messages, which may be widely scattered around, you might have difficulty finding performance bottlenecks; this is not meant to say that I think that style unsuitable, just something to keep in mind.

You are right. One thing I never mentioned is that in E there is no single entry point to an actor (vat). All non-value objects (including closures) are proxied when exposed to the outside world and act as entry-points for the actor. Of course, this is only possible in a dynamically strong-typed environment where my method returns Int but the proxy can return Promise[Int].

Fitting something similar into Akka does mean that we get these special objects (Futures) that can magically act as additional entry points to the actor. Still, I am convinced this is the best way to fit non-blocking futures with actors.

That depends on the use-case: if you want to achieve maximum throughput then allocating a closure, wrapping it in a message package, creating a Future and its AskActorRef etc. is not what you want. I agree that it makes certain things nicer to write down, but this approach comes with some restrictions (like the one about closing over an old actor instance’s state after restart).
 
This approach gives actors+non-blocking futures a very definitive edge over existing non-blocking APIs which take an listener object and invoke it on some indeterminate thread in the future, and you need to worry about synchronization over your shared state.

I firmly believe that we have this edge without implementing E-style ;-)
 
 
I would be very interested in seeing an implementation of this idea: with Akka we have a very robust platform on which to build more “fancy” stuff, and as you probably found while writing your prototype it is readily extensible.

At this point my prototype is not coupled to a particular actors implementation, since it only relies on !. In order to fully support Akka, including supervisors and cross-JVM transparency, it will have to become tightly coupled.

Yes, it definitely would.
 
So far, I have to applaud you guys for eliminating global state in Akka 2.0. Thank you!

You are most welcome! Good to see that the effort is appreciated.
 
 
I could imagine adding such a contribution as a trait to be mixed into Actor which would give you this behavior, should be doable by overriding receive() for handling the message and wrapping Future to carry along the sender reference, which you could capture e.g. by pimping a new ?? onto ActorRef or some such.

I also would like to applaud you for simplifying the API and getting rid of !!, !!, !? etc in Akka 2.0. I would not dare ask for any new multi-letter operators.

Yes, agreed on the motivation, but my suggestion was merely for the “external project experiment” phase. What you could also do is explicitly wrap ActorRefs when performing this kind of special send operation, as in `sendEstyle(target) ! request handleResponse { ... }` (bad names, but you get the idea)
 
 
Depending on how it works out, we could then also weave it more tightly into Actor, ActorRef and Future, but given that there are valid use cases for onComplete & friends without actors which should retain their semantics, I would prefer to have separate syntax for this feature.

Agreed. The abundance of features in Akka, such as STM, Dataflow, and standalone pipelining Futures, makes adopting new semantics for futures when used with actors a challenging problem.

:-)

Regards,

Roland

jlezard

unread,
Dec 12, 2011, 6:33:31 PM12/12/11
to Akka User List
Hello,

Very sorry but I am a bit confused about what is the problem Nikolay
is describing ( I don't know much about Threads being from
statistics... ) . And it gets me worrying about the following pattern
which seems to always come up.

Say you have a function

crawl: String -> Future[String]


class Crawler extends Actor {
def receive = {
case link: String => {
val html = crawl(link)
html onComplete {
_.value.get match {
case Left(problem) => handleCompletedWithException(problem)
case Right(result) => self ! result // or something like this
}
}
}
}
}

Is this okay ? Am I safe ?

Thanks,

Joe

On Dec 11, 9:52 pm, Nikolay Botev <bono8...@gmail.com> wrote:
> Hi Martin,
>
> On Fri, Dec 9, 2011 at 4:46 AM, Martin Grigorov

> <martin.grigo...@gmail.com>wrote:

√iktor Ҡlang

unread,
Dec 12, 2011, 6:34:30 PM12/12/11
to akka...@googlegroups.com
Hi Joachim,

On Tue, Dec 13, 2011 at 12:33 AM, jlezard <joachim...@gmail.com> wrote:
Hello,

Very sorry but I am a bit confused about what is the problem Nikolay
is describing ( I don't know much about Threads being from
statistics... ) . And it gets me worrying about the following pattern
which seems to always come up.

Say you have a function

crawl: String -> Future[String]


class Crawler extends Actor {
   def receive = {
     case link: String => {
       val html = crawl(link)
       html onComplete {
                 _.value.get match {
                   case Left(problem) => handleCompletedWithException(problem)
                   case Right(result) => self ! result // or something like this
                 }
               }

This is perfectly fine.

Cheers,

 
     }
   }
 }

Is this okay ? Am I safe ?

Thanks,

Joe

On Dec 11, 9:52 pm, Nikolay Botev <bono8...@gmail.com> wrote:
> Hi Martin,
>
> On Fri, Dec 9, 2011 at 4:46 AM, Martin Grigorov
> <martin.grigo...@gmail.com>wrote:
>
>
>
> > It will be even better if there is a way to set the context, as in
> > JavaScript with Function.prototype.bind or Function.prototype.apply's
> > first argument.
>
> This is an interesting comment, but I would rather not go there. Scala is
> very different from Javascript.
>
> Cheers,
> -Nikolay

--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.

jlezard

unread,
Dec 12, 2011, 6:51:12 PM12/12/11
to Akka User List
Ah great!

Thanks,

Joe

> Typesafe <http://www.typesafe.com/> - Enterprise-Grade Scala from the
> Experts
>
> Twitter: @viktorklang

rkuhn

unread,
Dec 13, 2011, 5:38:58 AM12/13/11
to akka...@googlegroups.com


Am Dienstag, 13. Dezember 2011 00:34:30 UTC+1 schrieb Viktor Klang:
Hi Joachim,

On Tue, Dec 13, 2011 at 12:33 AM, jlezard <joachim...@gmail.com> wrote:
Hello,

Very sorry but I am a bit confused about what is the problem Nikolay
is describing ( I don't know much about Threads being from
statistics... ) . And it gets me worrying about the following pattern
which seems to always come up.

Say you have a function

crawl: String -> Future[String]


class Crawler extends Actor {
   def receive = {
     case link: String => {
       val html = crawl(link)
       html onComplete {
                 _.value.get match {
                   case Left(problem) => handleCompletedWithException(problem)
                   case Right(result) => self ! result // or something like this
                 }
               }

This is perfectly fine.


Careful: what does handleCompletedWithException do? This will be executed on some other thread, possible concurrent with running the actor itself.

Regards,

Roland

Brice Figureau

unread,
Dec 13, 2011, 5:50:25 AM12/13/11
to akka...@googlegroups.com

Isn't it the same with the access to 'self'?

It might well be possible 'self' refers to a stopped/invalid actor at
the time the the onComplete block execute?

--
Brice Figureau
My Blog: http://www.masterzen.fr/

rkuhn

unread,
Dec 13, 2011, 5:53:44 AM12/13/11
to akka...@googlegroups.com


Am Dienstag, 13. Dezember 2011 11:50:25 UTC+1 schrieb Brice Figureau:
On Tue, 2011-12-13 at 02:38 -0800, rkuhn wrote:
>
>
> Am Dienstag, 13. Dezember 2011 00:34:30 UTC+1 schrieb Viktor Klang:
>         Hi Joachim,
>        
>         On Tue, Dec 13, 2011 at 12:33 AM, jlezard

Yes that may happen, but that’s fine: the message will be ignored in this case (with an exception in 1.x or sent to deadLetters in 2.0)

Regards,

Roland

Nikolay Botev

unread,
Dec 14, 2011, 3:12:18 AM12/14/11
to akka...@googlegroups.com
Joe,


On Tue, Dec 13, 2011 at 2:38 AM, rkuhn <goo...@rkuhn.info> wrote:

Careful: what does handleCompletedWithException do? This will be executed on some other thread, possible concurrent with running the actor itself.

In case you are still wondering, this is exactly the problem I was describing. As long as you understand what Roland is cautioning about - that onComplete executes concurrently in a temporary actor and the implications of that, you will be fine :-)

-Nikolay

Patrik Nordwall

unread,
Dec 14, 2011, 3:36:09 AM12/14/11
to akka...@googlegroups.com
Sneak preview of what we have in upcoming 2.0 docs:


    class MyActor extends Actor {
     var state = ...
     def receive = {
        case _ =>
          //Wrongs

        // Very bad, shared mutable state,
        // will break your application in weird ways
          Future { state = NewState }
          anotherActor ? message onResult { r => state = r }

        // Very bad, "sender" changes for every message,
        // shared mutable state bug
          Future { expensiveCalculation(sender) }

          //Rights

        // Completely safe, "self" is OK to close over
        // and it's an ActorRef, which is thread-safe
          Future { expensiveCalculation() } onComplete { f => self ! f.value.get }

        // Completely safe, we close over a fixed value
        // and it's an ActorRef, which is thread-safe
          val currentSender = sender
          Future { expensiveCalculation(currentSender) }
     }
    }

 

-Nikolay

--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--

Patrik Nordwall

Typesafe - Enterprise-Grade Scala from the Experts

Twitter: @patriknw


Nikolay Botev

unread,
Dec 14, 2011, 4:27:01 AM12/14/11
to akka...@googlegroups.com
Roland,

On Mon, Dec 12, 2011 at 9:04 AM, rkuhn <goo...@rkuhn.info> wrote:

That depends on the use-case: if you want to achieve maximum throughput then allocating a closure, wrapping it in a message package, creating a Future and its AskActorRef etc. is not what you want.

Futures for request-reply will always have more overhead than raw one-way fire-and-forget. E-style future however will most likely be more light-weight than the current implementation since no temporary actor needs to be created.
 
I agree that it makes certain things nicer to write down, but this approach comes with some restrictions (like the one about closing over an old actor instance’s state after restart).

True, this has some interactions with the failure recovery policies in Akka. It is not unresolvable though. In the other topic I raised a simple example where I can still shoot myself in the foot if I do not properly configure my actors (the Director/Executive contrived example). The key point is that if I have state and if that state evolves over the span of a conversation I have with another actor, closing over the current actor state for handling the reply is my implicit intent to begin with, and with the current Akka defaults, I will get in trouble already, even if I use idiomatic one-way message sends with the current semantics.

I think E-style semantics are actually good for bringing this problem to the forefront, because they make your original intent (dependency on my current state for handling the reply) explicit by closing over that state. I also think there are ways to address these interactions with E-style futures, in the same way that you would have to address them anyway in your application design today. It might be even better to address those design issues and make those choices once in the design of E-style futures instead of having to do it every time in your application.
 
 
This approach gives actors+non-blocking futures a very definitive edge over existing non-blocking APIs which take an listener object and invoke it on some indeterminate thread in the future, and you need to worry about synchronization over your shared state.

I firmly believe that we have this edge without implementing E-style ;-)

I fully agree with you. I started using Akka about 6 months ago, and Akka really has no match or even alternative in the Java world today for building truly scalable concurrent software.

Based on the discussion and feedback I have gotten here so far, though:

I do not see ask+onComplete as contributing to Akka's edge. If anything, it has the potential to hurt Akka's image. I would not recommend ask+onComplete for use to anyone for any reason. For high throughput, like you said, idiomatic actors are king. If I want to handle a response in a temporary actor, I will spawn one myself explicitly.

When I started with Akka earlier this year, I used typed actors with one-way message sends exclusively because I did not have the time then to explore how Akka Futures work. Things worked great and I was able to quickly show how Akka can be used to build truly a very high performance system with very simple code. Now when we have to turn prototype into production code and involve other engineers in writing Akka code, idiomatic Akka with one-way messages remains our best option. After looking at Akka Futures carefully (in the context of ActorRef.ask and typed actors), I do really do not see them as a viable alternative.

I think that Futures in Akka today conflate two distinct concerns that should really be kept separate.
On the one hand you have scalaz-style monadic futures, which works great, but is really something that sits on top of actors - actors/actor dispatchers are just an implementation detail about how you schedule your chain of computations that you can beautifully express by composing Future tasks.
On the other hand you have an attempt to provide a mechanism for doing request/reply between two actors in a non-blocking fashion (ask+onComplete). This is really something that is best done with actors in mind. Here you are living inside the world of actors, not riding on top of it. It's best to have something that cleanly and transparently integrates with actors and their semantics. In particular - no shared state, and reply goes to the sender, because this is what you want to do in the majority of cases. E-style Futures are designed for that. And they compose just as beautifully with map etc, as scalaz-style Futures do btw. Only they do so properly and safely in an actor context with intuitive semantics (in fact when { } in E is really map() in disguise).

Cheers,
-Nikolay

Nikolay Botev

unread,
Dec 14, 2011, 4:41:52 AM12/14/11
to akka...@googlegroups.com
Hi,

Thanks, this looks great. I just have one comment below:

On Wed, Dec 14, 2011 at 12:36 AM, Patrik Nordwall <patrik....@gmail.com> wrote:


          //Rights

        // Completely safe, "self" is OK to close over
        // and it's an ActorRef, which is thread-safe
          Future { expensiveCalculation() } onComplete { f => self ! f.value.get }

Doesn't this eat all exceptions coming from expensiveCalculation? Equivalent to writing

try { expensiveCalculation() } catch { _ => }

with a regular method call (except maybe the exception is logged by Akka)?

Thanks,
-Nikolay

Reply all
Reply to author
Forward
0 new messages