Scenario - A Queue has message objects. The queue is polled and messages are passed to message handlers. The message retrieval (poll) should be halted on client login event (one or more). I could use a wait/notify mechanism to achive this, but the advice from Joshua Bloch says , there is hardly any reason to use the cumbersome wait/notify mechanism with the advent of concurrent utilities. I am unable to make a choice as to which synchronizers (semaphore, cyclic barrier, countdownlatch) will fit my purpose. Any advice appreciated.
If the termination need not be immediate, you could use a "poison pill" pattern. When a user logs in, place a special "termination" object on the Queue. When you poll the Queue, check for that special, unique object. e.g.
public static final Message POISON_PILL = new Message();
...
in your loop {
Message message = queue.take();
if (message == POISON_PILL) // note usage of == here!
stopTheQueue();
else
normalProcessing(message);
}
This means that the Queue will process all Messages that were present before the user logged in. Which may be what you want.
If the stoppage needs to be immediate, check for Thread.interrupted() As described here. This requires that the login handlers know which Thread is handling the Queue, increasing coupling. So the "poison pill" is nice in that it has less coupling.
Related
I am reading the Akka (Java lib) docs and need clarification on some of their own proclaimed Akka/Actor Best Practices.
Actors should not block (i.e. passively wait while occupying a Thread) on some external entity...The blocking operations should be
done in some special-cased thread which sends messages to the actors which shall act on them.
So what does a code example of this look like in Akka/Java? If an Actor isn't an appriote place to put code that has to block, then what does satisfy the definition of "some special-cased thread"?
Do not pass mutable objects between actors. In order to ensure that, prefer immutable messages.
I'm familiar with how to make immutable classes (no public setters, no public fields, make the class final, etc.). But does Akka have its own definition of an "immutable class", and if so, what is it?
Top-level actors are the innermost part of your Error Kernel...
I don't even know what this means! I understand what they mean by "top-level" actors (highest in the actor/manager/supervisor hierarchy), but what's an "Error Kernel", and how does it relate to actors?
I am able to answer only the first question (and in future, please place only one question in a post).
Consider, for example, a database connection, which is inherently blocking. In order to allow actors to connect to a database, programmer should create a dedicated thread (or a thread pool) with a queue of database requests. A request contains a database statement and a reference to the actor which is to receive the result. The dedicated thread reads requests in a loop, accesses the database, sends the result to the referenced actor etc. The request queue is blocking - when there are no requests, the connection thread is blocked in the queue.take() operation.
So the access to a database is split in two actors - one places a request to the queue, and the other handles the result.
UPDATE: Java code sketch (I am not strong in Scala).
class Request {
String query;
ActorRef handler;
}
class DatabaseConnector implements Runnable {
LinkedBlockingQueue<Request> queue=new LinkedBlockingQueue<Request>();
Thread t = new Thread(this);
{t.start();}
public void sendRequest(Request r) {
queue.put(r);
}
public void run() {
for (;;) {
Request r=queue.take();
ResultSet res=doBlockingCallToJdbc(r.query);
r.handler.sendOneWay(res);
}
}
Here is the answer for your second question. Right from the Akka Doc:
If one actor carries very important data (i.e. its state shall not be
lost if avoidable), this actor should source out any possibly
dangerous sub-tasks to children it supervises and handle failures of
these children as appropriate. Depending on the nature of the
requests, it may be best to create a new child for each request, which
simplifies state management for collecting the replies. This is known
as the “Error Kernel Pattern” from Erlang.
So the phrase you talking about means that these actors are the "last line of defence" from errors in your supervision hierarchy, so they should be strong and powerful guys (commandos) instead of some weak workers. And the less commandos you have - the easier it would be managing them and avoid mess at the top-level. Precisely saying, the count of commando's should be near to the count of business protocols you have (moving to the superheroes - let's say one for IronMan, one for Hulk etc.)
This document also has a good explanation about how to manage blocking operations.
Speaking of which
If an Actor isn't an appriote place to put code that has to block then what does satisfy the definition of "some special-cased thread
Actor definetely doesn't, because Akka guarantees only sequentiality, but your message may be processed on any thread (it just picks-up a free thread from the pool), even for single actor. Blocking operations are not recommended there (at least in same thread-pool with normal) because they may lead to performance problems or even deadlocks. See explanation for Spray (it's based on Akka) for instance : Spray.io: When (not) to use non-blocking route handling?
You may think of it like akka requires to interact only with asynchronous API. You may consider Future for converting sync to async - just send response from your database as a message to the actor. Example for scala:
receive = { //this is receiving method onReceive
case query: Query => //query is message safely casted to Query
Future { //this construction marks a peace of code (handler) which will be passed to the future
//this code will be executed in separate thread:
doBlockingCallToJdbc(query)
} pipeTo sender //means do `sender ! futureResult` after future's completion
}
}
Other approaches are described in the same document (Akka Doc)
My program creates a message in a SQS queue and then needs to wait for one of the workers pulling work on the queue to process it. I want to monitor the status of a message to determine when it gets deleted, since that would be my indicator that the work is done. But I can't figure out a way to do this with the SQS API.
SendMessageRequest msgRequest = new SendMessageRequest(SQS_QUEUE_URL, messageBody);
SendMessageResult result = sqsClient.sendMessage(msgRequest);
String msgId = result.getMessageId();
// so, in theory, this is what I WANT to do...
while(!sqsClient.wasThisMessageDeletedYet(msgId))
Thread.sleep(1000L);
// continue, confident that because the message was deleted, I can rely upon the fact that the result of the Worker is now stashed where it's supposed to be
What's the right way to do "wasThisMessageDeletedYet(id)"?
I'm afraid such an API endpoint doesn't exist; looking at the API reference (http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Welcome.html), you could see that there are no methods for querying messages.
Maybe you could try with "change message visibility", but that:
has side effects
you would need to know the receipt handle which you obtain when receiving the message
So I suppose your best bet is to store that state in some external database (if you want to stay in Amazon-land, maybe Dynamo?). With a simple message id -> boolean mapping indicating if messages have been processed or not.
Another option (but similar) is for the consumer to publish the status in a response queue. The wait will have to be done asynchronously (a Future perhaps).
Obviously there an overhead in processing as well as complexity in programming due to the asynchronous nature of interactions. But typically it is done this way.
I have an application which applies the Producer-Consumer design pattern. IT is written in java. in short, the producers put items in a blocking queue and the consumers takes them from there. the consumers should run until signaled by a producer to stop.
what is the neatest way to deliver this signal from producers to the consumers? the chief designer said he wants to keep producer and consumer separate but I dont see any other other than invoking a method on consumer thread pool?
The Chief Programmer is right. Keeping them separate leads to highly decoupled code which is excellent.
There are several ways to do this. One of them is called Poison Pill. Here's how it works - place a known item on the Queue when the Consumer see that item, they kill themselves or take another action.
This can be tricky if there are multiple Consumers (you mentioned ThreadPool) or bounded Queues. Please look this up in Java Concurrency in Practice by Joshua Bloch. He explained it best.
Send a cancel message through the queue. Your consumers' run methods would look like
while(true) {
Message message = queue.take();
if(message == Message.Cancel) {
queue.offer(message); // so that the other consumers can read the Cancel message
break;
}
}
Create a ConsumerHalter class. Register all consumers that wants to get data from queue to the ConsumerHalter class, and have producer trigger a halt event in the ConsumerHalther class. The ConsumerHalter class then calls onStopConsuming() of each consumers.
I am scared to use event bus http://code.google.com/p/guava-libraries/wiki/EventBusExplained as I think its using unbounded queue internally. If a lot of message are post to it. It might run into full gc.
Is there exists a similar implementation which does the same thing which is unbounded queue?
Indeed, Guava uses an ConcurrentLinkedQueue, which is unbounded:
An unbounded thread-safe queue based on linked nodes.
See line 151-158 of EventBus.java.
/** queues of events for the current thread to dispatch */
private final ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>
eventsToDispatch =
new ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>() {
#Override protected ConcurrentLinkedQueue<EventWithHandler> initialValue() {
return new ConcurrentLinkedQueue<EventWithHandler>();
}
};
You could always modify the code to use e.g. ArrayBlockingQueue. Have you looked into other solutions that are similar, e.g. disruptor?
I do agree with Arjit that an unbounded queue can be considered disadvantageous in certain scenarios. For example, if I have a service running that consumes messages from various sources to process them and I don't know the rate of incoming messages. It might exceed the processing speed of my worker/consumer and I might want to establish the following contract: Posting new messages to the workers will fail or block if there are still many messages pending. This will not only prevent running out of memory but also guarantee that messages will actually be processed within a certain time frame. Additionally clients will receive direct feedback if the service is running at its limits.
#Arjit: You can check out MBassador on https://github.com/bennidi/mbassador
It is very similar to Google Guava event bus but offers more features - bounded message queues being one of them. It is also very fast and its internal design allows a great deal of customization and extension. Up to know, I was able to address most of the feature requests from other users within short periods of time. Maybe you give it a try.
Before I reinvent the wheel, is there a topic-like concurrent queue in plain Java? I have the following requirements:
Multiple readers/consumers
Multiple writers/producers
Every message must be consumed by every (active) consumer
After every consumer reads a message it should become garbage (i.e. no more references)
Writing to the queue should not be O(N) to the number of consumers
Concurrent, preferably non-blocking
Not JMS based: it's for a much lighter/embeddable environment
That's pretty much everything I need. Any pointers?
Basically you are talking about multiplexing, and no there isn't something in the standard lib but it is pretty simple to create one. Presuming that your clients aren't interested in messages published before they subscribe then you need a pool of queues for each consumer and publication simply offers the item to each queue:
public class Multiplexer<M> {
private final List<BlockingQueue<M>> consumers
= new CopyOnWriteArrayList<BlockingQueue<M>>();
public void publish(M msg) {
for (BlockingQueue<M> q : consumers) {
q.offer(msg);
}
}
public void addConsumer(BlockingQueue<M> consumer) {
consumers.add(consumer);
}
}
This version allows consumers to use whatever blocking queue implementation they might want. You could obviously provide a standard implementation and a nice interface for the client if you want.
the 3rd condition is not in plain java but you can use a nonblocking linked queue with a separate head for each consumer (you can rely on GC to collect the unreferenced nodes)
The simplest strategy is to pass a message to every consumer, I wouldn't have so many consumer that the number of consumers is important. You can add messages to dozens of consumers in a few micro-seconds.
One way to avoid this is to have a circular ring buffer with many readers. This is tricky to implement and means the consumers will be limited in the number of sources of message they can have.
Have just one pseudo-consumer and let the real consumers register with the pseudo-consumer. When a producer sends a message, the pseudo consumer wakes up and consumes the message. On consuming the message, the pseudo-consumer creates a separate Runnable for each real consumer registered with it and executes them on a thread-pool.