Java Reference
In-Depth Information
Message objects are stored in a java.util.LinkedHashMap so that they can be easily
looked up when a chat client makes a GET request. The key of this map is the id of the Mes-
sage . The service will always queue the last 10 messages posted to the server. We use a
LinkedHashMap so that we can easily evict the oldest chat message when the maximum
number of buffered messages is reached. The removeEldestEntry() method is used to de-
termine when to evict the oldest entry in the map. It simply checks to see if the size of the
map is greater than the maximum amount of messages. It then resets what the first mes-
sage is. Returning true triggers the removal of the eldest entry.
protected AtomicLong counter = new
new AtomicLong ( 0 );
The AtomicLong counter variable is used to generate message IDs.
LinkedList < AsyncResponse > listeners = new
new LinkedList < AsyncResponse >();
The listeners variable stores a list of waiting chat clients. We'll see how this is used later.
ExecutorService writer = Executors . newSingleThreadExecutor ();
We will have one and only one thread that is responsible for writing response messages back
to the chat clients. Having one writer thread is what makes this whole application scale very
well. Without asynchronous JAX-RS, this service would require a thread per blocking chat
client. While most modern operating systems can handle one or two thousand threads, sys-
tem performance starts to degrade quickly with all the context switching the operating sys-
tem has to do. Asynchronous JAX-RS allows us to scale to a much larger number of concur-
rent users.
Posting a new message
Let's look at how the service handles a new chat message:
protected UriInfo uriInfo ;
@Consumes ( "text/plain" )
public void
void post ( final
final String text )
final UriBuilder base = uriInfo . getBaseUriBuilder ();
writer . submit ( new
new Runnable ());
Search WWH ::

Custom Search