I am bit confused looking at the docs here and here
receive() is a method which accepts no parameters and returns a Partial function. tell() is a method which returns Unit and it 'sends' the message. Now for the message to be processed in my understanding 2 things have to happen:
The receive() should be invoked by tell
The message is passed to the partial function which is returned by the receive()
Now if the partial function is returned back to the place where tell() was used, then how does message based communication work? Why isn't the operation being performed inside the actor itself?
Because it is internals there is no documentation, but you can checkout source code yourself here: https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/actor/ActorCell.scala. All internals starting from how tell sends message to mailbox, how message is extracted from it, how receive is called and so on is here.
Hope it answers your question.
Related
I am using ReplaySubject as a pipe when I feed the Observer with OnNext messages and then I subscribe to the message in another part of the code.
I tried ISubject first, by using Subject.Create(observer:, observable:) but this seems to do nothing, or in other words, the Observer is a sink that goes nowhere. Is there some code that will make the Subject do something pipe-like. For example, I want to inject onNext messages with a integral countN and I want the observable to broadcast N-many 0.00E0(s) in sequence.
UPDATE:
It seems I need to implement the ISubject interface. Is there source code for a simple implementation that functions the same as ReplaySubject, with simple, proper memory handling of buffer size and Observer collection and Disposable return object.
Ok, so you use
new Subject<Int32>()
to get a subject that is a pipe-line.
Someone care to explain what Subject.Create does?
Can you inherit from Subject or ReplaySubject? Should you be able to?
I'm using the Play Framework with scala. I'm new to scala, akka, and play.
This is my actor system. I'm not sure I'm doing this right, but I have 2 routers. 1 for Actor A, and 1 for Actor B:
val system = ActorSystem("ActionSystem")
val actorARouter = system.actorOf(Props[ActionParser].withRouter(
SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorARouter")
val actorBRouter = system.actorOf(Props[ActionDispatcher].withRouter(
SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorBRouter")
This is the current setup that I have:
The play framework provides a Controller for me that receives a http rest call with some json. Whenever the Controller receives a rest call, I do an ask sends the json to a router for Actor A. Here is what that looks like:
(actorARouter ? request.body.asJson.get).map {
case m: controllers.HttpMessages.OK => Ok(m.body)
case m: controllers.HttpMessages.HttpResponse => Status(m.status)(m.body)
}
Actor A then parses the json into a Seq of objects and then sends them via an ask to Actor B. Actor B is supposed to eventually process those by sending them to other actors, but for now is just returning generic responses.
The generic responses are being received back by ActorA via the future, then being parsed to JSON and then returned to the Controller via an OK response... or at least that's what is supposed to happen.
What's happening:
So what's happening is the controller sends to ActorA, ActorA sends to ActorB. ActorB sends generic responses to ActorA. ActorA parses generic responses into JSON and tries to do sender ! OK(json) but I get a message in the console saying it wasn't delivered as it's a "dead letter". when I debug into it when I look at sender, sender is a reference to the actor akka://ActionSystem/deadLetters
My questions:
Obviously I'm doing something wrong. Maybe I shouldn't be chaining these actors responses together like this. Again, I mentioned I only had plans to further this by having ActorB send out requests to other actors.
When I do an ask in an actor, that doesn't hog that thread and stop it from processing other messages while it's waiting for a response does it?
EDIT:
I found out I can save a reference to the sender for later use, and then send to that, and that seems to fix the dead letter problem. But I'm still very uncertain if this is the right way to be doing things. It feels like every time I'm adding another layer of actors 10's of milliseconds are being added onto my response time. Perhaps that's due to other factors though.
Without looking at your code, I cannot really comment on what caused the dead letter, from your edit I guess you closed over sender() instead of assigning it to a variable and closing over that.
To respond to your questions:
It is much easier to construct message flows with actors if you only use fire-and-forget messages. The ask Pattern is useful in some cases, but most of the time you should try to avoid it. What you can do instead is to pass the original sender along through your actors by using forward instead of tell. This way a response can be generated by the last actor in your message flow. The first actor only needs the code to handle the response, and does not need to care about generating the response. Nice separation of concerns right there. If you need to aggregate several responses in order to send out a single response afterwards, you can also use a temporary actor that all other actors will send their response to, and that knows the orignal sender. Temporary actors need to be stopped after doing their work.
As far as I know the ask pattern is asynchronous and uses temporary actors internally. However, if you wait for the result of the future in your actor, that will block that actor, and it will not be able to process further messages. A nice method to use the ask pattern is in combination with the pipeTo Pattern, which you can use to send the result of ask to an actor (usally self)
Javadoc for RequestContext#fire() says only:
Send the accumulated changes and method invocations associated with the RequestContext.
GWT Moving Parts wiki entry under Flow section says only:
All accumulated operations will be applied to the domain objects by traversing properties of the proxies.
All method invocations in the payload are executed.
But will these methods be executed on the server side in the same order they were "executed" (accumulated) on ReqestContext instance on client side?
For my situation, if I execute on client side:
context.persist().using(proxy)
context.find(proxy.stableId().to(updatingReceiver))
context.fire()
Then may I be sure that on server side find() will be invoked after persist() so my updatingReceiver will get proxy of updated (persist()'ed) entity as an argument?
EDIT:
Going further, may I be sure that back on client after response Recievers will be invoked in exactly the same order in which their corresponding methods were accumulated?
Finally, is there a way to add some action that will be invoked at the end of response handling, after all Receivers' actions?
I thought something like this may work:
requestContext.fire(new Receiver<Void>() {
#Override
public void onSuccess(Void response) {
//Things to do after all receivers
});
And it really seems to work as I expected but because all that Javadoc is telling me about RequestContext.fire(Receiver) method is:
For receiving errors or validation failures only.
I'm not 100% sure whether my assumption is correct.
Yes, order of method invocations is preserved, both on the server-side and then back on the client side when calling Recievers.
The queue is a simple ArrayList in which invocation objects are appended. On the server-side, they're processed in the order they're received.
The Request-Context-level Receiver is always called after the ones for invocations. Its onSuccess is always called, whatever the result of the invocations (even if they all fail), to signal that the batch of invocations was processed successfully. Its onFailure is only called in case of a general failure, i.e. a network error, or an error when (de)serializing requests/responses on the server-side.
See http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java?r=10835#345
In the past, I have used libraries that would allow me to register a callback so that the library can call my method when some event happens (e.g. it is common to see in code that use GUI libraries to look like button.onClick(clickHandler)).
Naively, I suppose the library's handling mechanism could be implemented like:
while(1){
if (event1) { event1Handler(); }
if (event2) { event2Handler(); }
...
}
but that would be really wasteful right? Or is that really how it is done (for instance do well known GUI libraries like java swing, or GTK+ do it this way)?
background:
This question hadn't really occured to me until I encountered curses. I thought about implementing my own callback system, until I realized I didn't know how.
The while loop will typically wait for an interrupt from the user (GetMessage in Windows). When an interrupt arrives GetMessage returns and then it ends up in the callback function. The if statements are typically implemented as a switch-case. See Windows Message Loop on Wikipedia.
In more detail, what happens is the following:
The user application calls GetMessage, which forces the process to sleep until an input message for that application arrives from the systems queue. When a message arrives, the user app calls DispatchMessage, which calls the callback function associated with the window that the message was aimed at.
Windows API uses one callback which handles all events in a switch case. Other libraries use one callback per event class instead.
The function pointers themselves are stored together with other window data in a struct.
Callback system implementation probably has different implementation in different technologies, however, I suppose they should be working this way:
A data structure stores the callback IDs and pointers to the handlers.
A callback handler has a validator
Event handlers have callback callers, which know what are the possible callbacks and check their validity this way:
for each callback in event.callbacks
if (callback.isValid())
call callback()
end if
end for
When you add a handler to a function the system will automatically know where the callback is valid and will add the callback to the datastructure described in 1.
Correct me if I'm wrong, this description is just a guess.
Is it a function?
Is it a function being called from the source?
Or, is it a function being returned from the destination?
Or, is it just executing a function at the destination?
Or, is it a value returned from a function passed to the destination?
A callback is the building block of asynchronous processing.
Think of it this way: when you call someone and they don't answer, you leave a message and your phone number. Later on, the person calls you back based on the phone number you left.
A callback works in a similar manner.
You ask an API for a long running operation and you provide a method from within your code to be called with the result of the operation. The API does its work and when the result is ready, it calls your callback method.
From the great Wikipedia:
In computer programming, a callback is
executable code that is passed as an
argument to other code. It allows a
lower-level software layer to call a
subroutine (or function) defined in a
higher-level layer.
Said another way, when you pass a callback to your method, it's as if you are providing additional instructions (e.g., what you should do next). An attempt at making a simple human example follows:
Paint this wall this shade of green (where "paint" is analagous to the method called, while "wall" and "green" are similar to arguments).
When you have finished painting, call me at this number to let me know that you're done and I'll tell you what to do next.
In terms of practical applications, one place where you will sometimes see callbacks is in situations with asynchronous message passing. You might want to register a particular message as an item of interest for class B.
However, without something like a callback, there's no obvious way for class A to know that class B has received the message. With a callback, you can tell class B, here's the message that I want you to listen for and this is the method in class A that I want you to call when you receive it.
Here is a Java example of a callback from a related question.