IIIMSF implementation note | ||
---|---|---|
Prev |
In general, the design of dynamics is the most important but difficult subject. If it is complicated, the software will have many problems, to make matters worse, these are hard to resolve, and the further change tends to be a nightmare.
In order to reduce such difficulties, in IIIMSF, I separated the part that rules concurrency from the others, which is the scheduler. The scheduler is a very small portion, and its requirements are fully encapsulated by IMSchedule class. IMSchedule class is an abstract class, thus it has naturally one or more concrete subclasses (currently, IIIMSF has only IMScheduler_MTPC for it).
IMScheduler has an instance of IMProtocol, and by actively calling the method of it, it decides what operation should be dealt with next. IMScheduler_MTPC (MTPC means Making a Thread Per Connection) is one of the simplest implementaion of IMScheduler, it just creates one thread every time IMProtocol makes IMState object.
The main part must choose which implementation of IMScheduler is
used. Currently, it initializes IMScheduler_MTPC by calling
IMScheduler::construct
at the startup.
In contrast to the scheduler, the protocol handler does not touch with concurrency policy. Instead, it has a responsibility for the synchronization, and the protocol state. Every time invoked from the scheduler, the protocol handler properly manage the current state; receive the messages from and send ones to clients.
Therefore, in principle, the protocol handler must not block execution flow. For example, because I/O operations may block the execution, the protocol must use overlapped I/O or check whether I/O operations are available before actually processing them.
Since IIIMP is stateful protcol, the protocol handler must deal with the transition of protocol state, and maintain the current state per each input context.
In this protocol handler, `state' pattern is adopted to manage it. This pattern represents the kind of state by class. For example, IIIMP_ICState class represents the base state of input context, and IIIMP_ICState_REQUESTED class represents the state that something is now requested by a client.
In order to avoid updating references owned by other objects when a state is changed, we adopt the proxy pattern. When changing a current state, we actually do the following:
Create a new object for a new state (i.e. its class represents the kind of the state.)
Relate the reference of this object to the base state object.
When the base object accepts a message, forward it to the new object.
From the protocol handler, the main part must behave as a passive object. In principle, it must not actively calls any methods of the protocol handler.
There is one exeption for it. The main part (or the other entities) may call IMLExec::push_insts() actively. Because it only queues IML instruction, and then return immediately. Thus, it does not block the execution flow. In this meaning, IMLExec is not a part of the protocol handler, but this object is passed to the protocol handler, and executes IML instructions by interacting ICState or IMState objects so that we should regard it as a part of the protocol handler.