Sunday, December 7, 2014

Custom ThreadPoolExecutor based on spinlock approach.

      In one project we used ActiveMQ(JMS API) to communicate between business services and custom engine that worked asynchronously behind the scene to process financial data.
The flow to add/remove entity from ui was done as it usually organized in context of three-tier architecture: call to ui controller, route appropriate method, use service and then DAO to add/delete entity and then notify active mq corresponding consumers to process add/delete actions.

     But the issue was in the following: entity might be created in database, but not fully processed by engine while user tries to delete it from web interface.
It's not the issue on the  database side, this is multithreading synchronization question.

    I decided to use spin lock approach to sync two add/delete threads that did their work when the corresponding messages came to ActiveMQ queue.

    This is how JMS handler looks like. When message comes to queue it's then appropriate handled by  tickerEngineRequestProcessor, that is simply container for ThreadPoolExecutor performing tasks execution(add or delete one).

     Below is definition for tickerEngineRequestProcessor:
Let's now describe TickerTask, it just implemented Runnable interface to be processed within custom spin lock thread pool which I will describe further.

   The main idea in TickerEngineAddRemoveSyncThreadPoolExecutor is to perform spin iterations on thread that performs removing ticker while thread which adds ticker is not finished yet. This logic is placed in beforeExecute action. In afterExecute we just remove corresponding tickerId key from tickerIdsToAddInProgressState set.
   One more word about tickerIdsToAddInProgressState. This is ConcurrentHashSet that I choosed for storing state as per given tickerId, because we need to maintain sync add/remove operations based on the given tickerId and don't affect other tickers that might be processed at the same time. Thread.yield() is signal for threads scheduler to switch its work to other threads but the yielding thread can be scheduled back in one interrupt period later.






No comments:

Post a Comment