Library Architecture


InfoBus

The heart of the communication mechanism of the library is the InfoBus service. InfoBus allows multiple service threads to send messages to one another asynchronously without worrying whether the recipient of the message even exists. The messages in this system are called items.

InfoBus consists of several blocking queues where a thread can post an item. A thread posting the item continues its work immediately, however the recipient of the item is blocked on its own queue until the item arrives. A recipient thread does not need to know what kind of item it is receiving: the item itself takes care of the logic behind it.

This situation is shown below:

Image:Proxy1.GIF


However, the thread posting an item does not need to worry whether the recipient thread exists or not. If the recipient thread has not been started yet, the item will be kept inside the InfoBus, until it is taken by the intended party. So, the following situation is also possible:


Image:Proxy2.GIF


In this case the recipient thread does not wait on the InfoBus for the next item, because the item is already there. Of course, there can be as many items as needed from many different threads.

In reality, as was said, InfoBus consists of a number of blocking queues – one per service thread. The queues are created on demand, i.e. when a thread is posting an item to another thread which queue does not exist yet, InfoBus will create the queue and put an item into it. No matter how long it will take for a recipient thread to be started (if at all), the item will be kept in the queue by InfoBus indefinitely. This guarantees that all the items will be delivered to their recipients regardless of when the recipient threads start.

Next figure demonstrates the communication blocking queues inside the InfoBus:

Image:Proxy3.GIF


Service Threads

The proxy server application consists of a number of threads, called here service threads, that can easily and asynchronously communicate with each other using the InfoBus architecture described above. The application logic is contained in the items posted by service threads to each other. The thread receiving an item, executes it and can in turn post some other item(s) for other thread(s) to execute based on the outcome of the previous operation.

The lifecycle of a service thread is very simple. It starts, listens to the InfoBus incoming items, retrieves them, executes them and continue to listen again. So, when there is no work, the service thread is blocked on its communication queue of the InfoBus. Next figure represents the lifecycle of a service thread:

Image:Proxy4.GIF

Communication Queue Items

Communication queue items are classes inheriting from the CommQueueItem class. All they need to do is to define the method called execute and put some application logic into it. This method will be executed after a service thread whose communication queue contains the item picks up the item from the queue.
As was previously said, a service thread executing a communication queue item does not really care about the logic inside the item: it just calls the execute method of the current item and continue to listen on its communication queue inside the InfoBus.


Service Launcher

Service Launcher is a focal point of all the functionality provided by the library. It creates service threads, keeps them alive even if some of them fail on an uncaught exception and provides methods to stop service threads gracefully or immediately.
Graceful shutdown means that all service threads will execute all items that were waiting in their communication queues until the point where the shutdown process was initiated and only then the threads will exit.
Immediate shutdown means that all service threads will be interrupted in the middle of their current tasks.

Service threads can be started one by one or using a batch method which will start any number of services giving them identifiers automatically.

Service threads are not intented to be stopped one by one. The purpose of the service is to run indefinitely until the application exits. If there is no task for the service thread to perform, the thread will be blocked indefinitely on its InfoBus queue. Thus, the lack of tasks for a service is practically equal to the situation when the thread is not running at all.