I have a server application that listens on a ServerSocket for incoming queries. The clients submitting the queries expect to open a socket to the server, pass their query upstream, and then (possibly after a short period of time) read the response to their query from the same socket that they used to submit the query.
For this I am trying to use an ExecutorCompletionService. Different query classes are passed to different Callables, but all are expected to return a String as their result.
All of this is quite manageable until I reach the stage of actually trying to reply to the clients. The Future objects are currently all of type Future<String>, but I am unable to marry that result (the String) up to the appropriate Socket.
My solution is about to be to make all of my Callables be of type Callable<StringSocketPair> where StringSocketPair looks like;
public class StringSocketPair {
Socket sock;
String content;
}
But this all seems a little odd, as now I have to pass the Socket to the Callable constructor, so that it can return it alongside the String result from its call() method. All so that I can push the String onto the Socket in yet another thread which polls ExecutorCompletionService.take().
The other option is to use Runnables instead of Callables and have each Runnable task respond on its own Socket, but as I have a dozen or so query types, each has their own task object, and I'd rather not have to add a respondToClient() call of some kind to the end of every run() method for every task object.
There must be a simpler solution to what I would think is a fairly common setup?
Following the idea of using a Runnable, you could use the Template Method Pattern to define the functionality for responding. This would prevent you from having to write that common code for every task as the common code would be placed in the abstract parent class which implements Runnable.
Template Method Pattern:
abstract class TemplateSuperClass implements Runnable {
public void run() {
//some setup code here
String message = taskWork(...);
socket.write(message);
//common cleanup code
}
abstract String taskWork(...);
}
class HelloWorld extends TemplateSuperClass {
String taskWork(...) {
return "Hello World";
}
}
Otherwise, you are probably right to change the Callable to return the tuple of response message and socket.
Related
I am new to akka, looking at existing code and see an actor gets Message1 form others and then sends Message2 to self. I understand the advantage of sending messages over method calls is the key in akka. However I do not see advantage in sending message to getSelf(). The code I see looks like this:
import java.util.Date;
import akka.actor.AbstractLoggingActor;
import akka.actor.Props;
public class myActor extends AbstractLoggingActor {
public static class Message1 {
}
public static class Message2 {
}
private Date date;
public static Props props(Date date) {
return Props.create(myActor.class, date);
}
#Override
public Receive createReceive() {
return receiveBuilder().match(Message1.class, message -> {
// some state change here, method calls, ...
getSelf().tell(new Message2(), getSelf());
}).match(Message2.class, message -> {
// some code here ...
this.doSomeLongProcessing();
}).build();
}
private void doSomeLongProcessing() {
// ... long time is taken here
}
}
Eventually there should be a blocking call to a method in the actor class (e.g. doSomeLongProcessing()) and we put this call in another message processing it will not be any better.
In this light the question is - why we may need to send messages to self in akka ?
Please explain as I saw some examples of this on the web as well.
I don't think I can give a real answer without seeing the complete code and context. But, in general, you are right, under normal circumstances there's not a whole lot of benefit to sending yourself a message just to continue normal processing. But I expect that this example is a bit contrived anyway because ordinarily you wouldn't want to mix blocking and non-blocking behavior in the same actor. (In general, the best practice would be to process message1 in one actor and then process message2 in a different actor so that you could put that second actor in a dedicated thread pool for blocking actors.)
There are several situations, however, where sending messages to yourself can be valid. Two of which are mentioned by Robert Harvey above in the comments: when using timers to send a message to yourself in the future and the "pipeTo" pattern where you are sending yourself a message from inside a Future completion. (This is important because you will no longer be inside the actor context in the completion handler, so you need to send yourself a message in order to get back into the context.)
I can also think of a few other edge cases where you might want to send a message to self. For example, if you are in a blocking actor, sending a message to yourself is effectively a yield allowing the actor to handle others messages.
If the code is public I could take a look at a specific example in more detail.
I've found a lot of examples about it and doesn't know what's the 'right' implementation right there.
Basically I've got a object (let's call it NBAManager) and there's a method public Completable generateGame() for this object. The idea is that generateGame method gets called a lot of times and I want to generate games in a sequential way: I was thinking about concurrent queue. I came up with the following design: I'd create a singleton instance of NBAService: service for NBAManager and the body of generateGame() will look like this:
public Completable generateGame(RequestInfo info)
return service.generateGame(info);
So basically I'll pass up that Completable result. And inside of that NBAService object I'll have a queue (a concurrent one, because I want to have an opportunity to poll() and add(request) if there's a call of generateGame() while NBAManager was processing one of the earlier requests) of requests. I got stuck with this:
What's the right way to write such a job queue in Rx way? There're so many examples of it. Could you send me a link of a good implementation?
How do I handle the logic of queue execution? I believe we've to execute if there's one job only and if there're many then we just have to add it and that's it. How can I control it without runnable? I was thinking about using subjects.
Thanks!
There are multiple ways to implement this, you can choose how much RxJava should be invoked. The least involvement can use a single threaded ExecutorService as the "queue" and CompletableSubject for the delayed completion:
class NBAService {
static ExecutorService exec = Executors.newSingleThreadedExecutor();
public static Completable generateGame(RequestInfo info) {
CompletableSubject result = CompletableSubject.create();
exec.submit(() -> {
// do something with the RequestInfo instance
f(info).subscribe(result);
});
return result;
}
}
A more involved solution would be if you wanted to trigger the execution when the Completable is subscribed to. In this case, you can go with create() and subscribeOn():
class NBAService {
public static Completable generateGame(RequestInfo info) {
return Completable.create(emitter -> {
// do something with the RequestInfo instance
emitter.setDisposable(
f(info).subscribe(emitter::onComplete, emitter::onError)
);
})
.subscribeOn(Schedulers.single());
}
}
I'm new to akka and I'm trying akka on java. I'd like to understand unit testing of business logic within actors. I read documentation and the only example of isolated business logic within actor is:
static class MyActor extends UntypedActor {
public void onReceive(Object o) throws Exception {
if (o.equals("say42")) {
getSender().tell(42, getSelf());
} else if (o instanceof Exception) {
throw (Exception) o;
}
}
public boolean testMe() { return true; }
}
#Test
public void demonstrateTestActorRef() {
final Props props = Props.create(MyActor.class);
final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testA");
final MyActor actor = ref.underlyingActor();
assertTrue(actor.testMe());
}
While this is simple, it implies that the method I want to test is public. However, considering actors should communicate only via messages, my understanding that there is no reason to have public methods, so I'd made my method private. Like in example below:
public class LogRowParser extends AbstractActor {
private final Logger logger = LoggerFactory.getLogger(LogRowParser.class);
public LogRowParser() {
receive(ReceiveBuilder.
match(LogRow.class, lr -> {
ParsedLog log = parse(lr.rowText);
final ActorRef logWriter = getContext().actorOf(Props.create(LogWriter.class));
logWriter.tell(log, self());
}).
matchAny(o -> logger.info("Unknown message")).build()
);
}
private ParsedLog parse(String rowText) {
// Log parsing logic
}
}
So to test method parse I either:
need it to make package-private
Or test actor's public interface, i.e. that next actor LogWriter received correct parsed message from my actor LogRowParser
My questions:
Are there any downsides on option #1? Assuming that actors communicating only via messages, encapsulation and clean open interfaces are less important?
In case if I try to use option #2, is there a way to catch messages sent from actor in test downstream (testing LogRowParser and catching in LogWriter)? I reviewed various examples on JavaTestKit but all of them are catching messages that are responses back to sender and none that would show how to intercept the message send to new actor.
Is there another option that I'm missing?
Thanks!
UPD:
Forgot to mention that I also considered options like:
Moving logic out of actors completely into helper classes. Is it common practice with akka?
Powermock... but i'm trying to avoid it if redesign is possible
There's really no good reason to make that method private. One generally makes a method on a class private to prevent someone who has a direct reference to an instance of that class from calling that method. With an actor instance, no one will have a direct reference to an instance of that actor class. All you can get to communicate with an instance of that actor class is an ActorRef which is a light weight proxy that only allows you to communicate by sending messages to be handled by onReceive via the mailbox. An ActorRef does not expose any internal state or methods of that actor class. That's sort of one of the big selling points of an actor system. An actor instance completely encapsulates its internal state and methods, protecting them from the outside world and only allows those internal things to change in response to receiving messages. That's why it does not seem necessary to mark that method as private.
Edit
Unit testing of an actor, IMO, should always go through the receive functionality. If you have some internal methods that are then called by the handling in receive, you should not focus on testing these methods in isolation but instead make sure that the paths that lead to their invocation are properly exercised via the messages that you pass during test scenarios.
In your particular example, parse is producing a ParsedLog message that is then sent on to a logWriter child actor. For me, knowing that parse works as expected means asserting that the logWriter received the correct message. In order to do this, I would allow the creation of the child logWriter to be overridden and then do just that in the test code and replace the actor creation with a TestProbe. Then, you can use expectMsg on that probe to make sure that it received the expected ParsedLog message thus also testing the functionality in parse.
As far as your other comment around moving the real business for the actor out into a separate and more testable class and then calling that from in the actor, some people do this, so it's not unheard of. I personally don't, but that's just me. If that approach works for you, I don't see any major issues with it.
I had the same problem 3 years ago, when dealing with actors : the best approach i found was to have minimum responsability to the actor messenging responsability.
The actor will receive the message and choose the Object's method to call or the message to send or the exception to throw and that's it.
This way it will be very simple to mock up either the services called by the actor and the input to those services.
The server I'm developing has different tasks to perform based on messages received from clients, some tasks are very simple and require little time to perform, but other may take a while.
Adding an ExecutionHandler to the pipeline seems like a good solution for the complicated tasks but I would like to avoid threading simple tasks.
My pipeline looks like this:
pipeline.addLast("decoder", new MessageDecoder());
pipeline.addLast("encoder", new MessageEncoder());
pipeline.addLast("executor", this.executionHandler);
pipeline.addLast("handler", new ServerHandler(this.networkingListener));
Where MessageEncoder returns a Message object (for decode) which defines the requested task.
Is there a way to skip the execution handler based on the decoded message?
The question can be generalized to: is there a way to condition whether or not the next handler will be used?
Thanks.
Instead of using ExecutionHandler as is, you can extend it to override its handlerUpstream() method to intercept the upstream events and call ctx.sendUpstream(e) for the MessageEvents whose message meets your criteria. All other events could be handled by the ExecutionHandler via super.sendUpstream(e). That is:
public class MyExecutionHandler extends ExecutionHandler {
public void handleUpstream(ctx, evt) throws Exception {
if (evt instanceof MessageEvent) {
Object msg = ((MessageEvent) evt).getMessage();
if (msg instanceof ExecutionSkippable) {
ctx.sendUpstream(evt);
return;
}
}
super.handleUpstream(evt);
}
...
}
You can remove it (or add it on demand) from the pipeline inside your MessageDecoder before you send the message upstream. You can also check the message inside your executionHandler and just pass it upstream.
In case you cannot modify these two files you can create another handler which removes executionHandler based on the message type.
I have a centralized socket class which is responsible for sending and retrieving data. I have 2 classes:
one which listens to the input stream and
the other one which takes care of writing to it.
Listening running on an infinite loop and then process the messages. For synchronous i block the read and reset these values once i receive the response from the server.
Now i am stuck with asycnhronous. I have 3 methods in my service.
getSomething
readSomething
saySomething.
In my getSomething i want to implement async functionality based on the boolean flag provided. When my app starts i also start both of my threads and if i send concurrent request.
For example readSomething first and then getSomething then i get the return value for readSomething in getSomething which is not what i desire and i can see in the logs that the output for getSomething comes after a while.
It looks like the Future object requires to submit a new task which will run in it's own thread but the way i have design this app, i just can't create a new thread. Can anyone give me insights on how should i handle this asycnhronous like a flow chart etc ?.
If you're doing work Asynchronously, that means that other part of the application does not care when the async work is done.
What you'll normally want to do is notify the other part, when the async work is done. For this, you'll want to use the "Observer Pattern" (the article includes flow-charts).
The basic idea is, that your app starts the async work and is notified, when the work is done. That way, you can loosely couple two parts of the application. A quick example:
/**
* The observer
*/
public interface AsyncWorkDoneListener{
/**
* This method will be called when the async-thread is
* done.
*/
public void done(Object unit);
}
/**
* The worker (which does the asyc-work on another thread).
*/
public class AsyncWorker{
private AsyncWorkDoneListener listener;
/**
* Set (you might want to maintain a list here) the current
* listener for this "AsyncWorker".
*/
public void setListener(AsyncWorkDoneListener listener){
this.listener = listener;
}
/**
* Will do the async-work
*/
public void doWork(){
// Do the work in another thread...
// When done, notify the registered listener with the
// result of the async work:
this.listener.done(the_object_containing_the_result);
}
}
/**
* The application
*/
public class App implements AsyncWorkDoneListener{
public void someMethod(){
// Work on something asynchronously:
mAsyncWorker.setListener(this);
mAsyncWorker.doWork();
}
#Override
public void done(Object unit){
// The asyc work has finished, do something with
// the result in "unit".
}
}
A couple of insights:
you need dataflow, not flow charts
if you cannot create new thread for each task, you can use fixed-sized thread pool created by java.util.concurrent.Executors.newFixedThreadPool()
you cannot use Future.get() from within a task running in a threadpool, or thread starvation deadlock may occur.
your description of the problem is unclear: too many undeclared notions. "reset these values" - what values? "3 methods in my service" - is it server side or client-side? "boolean flag provided" - do we need to understand who provided that flag and what does it mean?
Please provide a dataflow representation of the program you need to implement in order we could help you.