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
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
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
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,
Thanks for the very constructive criticism.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/akka-user/-/sDtayngFKMwJ.
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?
-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.
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.
-Nikolay
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?
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? :-)
--
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
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.
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.
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,
√
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,
To post to this group, send email to akk...@googlegroups.com.
To unsubscribe from this group, send email to akka-u...@googlegroups.com.
--To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/SvQ6hDyn_9cJ.
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.
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
--
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.
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.
Up to now I have not seen anything which fits perfectly, and there may well not be a silver bullet for this one.
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.
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.
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.
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.
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.
Hi RolandOn 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.
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:
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
> <martin.grigo...@gmail.com>wrote:
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
>
>
>
> > 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.
Thanks,
Joe
> Typesafe <http://www.typesafe.com/> - Enterprise-Grade Scala from the
> Experts
>
> Twitter: @viktorklang
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.
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/
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
Careful: what does handleCompletedWithException do? This will be executed on some other thread, possible concurrent with running the actor itself.
-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
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 ;-)
//Rights
// Completely safe, "self" is OK to close over// and it's an ActorRef, which is thread-safeFuture { expensiveCalculation() } onComplete { f => self ! f.value.get }