I need some advise to meet following requirements. I have also posted how I have done it after the requirement. However, I am looking for better approaches, coz I think mine is not good enough. Can you please help to review it and let me what do you think from the architecture perspective?
Briefly, the requirement as follows,
The server should, upon starting up, load into memory a “dictionary” of synonyms words from a text file. The dictionary will be loaded in to a collection.
The client, which should run in a separate JVM, should, upon starting, enter an iterative cycle in which it repeatedly asks the end user the meaning of a word chosen “at random” from the dictionary. The user’s answer should be checked against the dictionary. A correct answer is one which matches.
The client must be as thin as possible, and must not cache dictionary contents.
If, upon attempting to retrieve a question or validate an answer, the client experiences a problem communicating with the server it should automatically recover if the server becomes available again, however the current question may be discarded in this case.
The dictionary may be huge containing hundreds of thousands of entries. It is most important that when the server is still loading the words, it be able to select random word from dictionary loaded so far and provide it as a question to client. Also, be able to check the answer returned from server is correct or not. So if the client has just restored contact with the server, there must be no noticeable delay before the first question is asked.
The server should not employ any kind of polling when determining the current size of its in-memory dictionary. You should make best use of multi-threading in order to optimise the implementation.
The server should allow large numbers of clients to connect to it simultaneously.
You may use either RMI or Sockets (of the blocking variety) to implement inter-process communication.
For the inter-process communication, I have used RMI to implements.
The dictionary content has been stored in a concurrentHashMap.
The key of the map is a single word and the value is the list of synonyms words (List of strings).
The reason I have chose this type of collection is that it is efficient when it looks for the synonyms words for a given word.
Using concurrentHashMap allows different threads access it concurrently.
The DictionaryServer starts three separate threads
Thread 1: working on loading the dictionary
Thread 2: looping through the dictionary to set the random keyword
In this case, the dictionaryServer is available to the client to query from the beginning. There won’t be a noticeable delay
when the dictionary size is getting bigger and bigger because the Thread2 – LoopThread will always iterate the dictionary key
size and provides a random keyword whenever you needs. No polling of dictionary size is needed to determin the random keyword.
However, while the Thread 1 – loading process is running at the same time, it might causes some delays as it consumed lots of resources.
On the client side, if the server is down, I use a separated thread to ping the server to see if it is up running. However,
personally, I don’t think this is the best solution to implements this as pinging can be expensive over the network.
It would be good to have a push back from the server to tell all the clients when it starts up. But I found it is difficult to do
with RMI, maybe using JMS is easier to do.
I have send you the code if any body interested. Seems doesn't allow me to attached my zip file.