Monday 21 June 2010

Week 24 of 2010

I worked on the Simulation subsystem of the OOA of OOA most of the week since OOA Tool 2 needs an OOA virtual machine immediately (all derived calculations will be coded using Action Language code rather than Java code). The bulk of the Simulation subsystem focuses on data populations and the instance data associated with different types of population.

Simple populations define Object Instances, Base Attribute Instances (simple, arbitrary ID and mathematically dependent attributes), Relationship Instances (simple, associative and subtype-supertype relationships) and Participant Instances. It also defines Counterpart Mapping Instances allowing object instances in one domain to be converted to counterpart object instances in another domain within bridging code. The only population dependent values that can be used in simple populations are object instance values. Any attribute instances with a population dependent type that isn't an object instance type will have an undefined value.

Arbitrary ID attributes have a current value representing an allocated arbitrary or ordinal ID. The system automatically allocates or reallocates IDs as and when needed within limits controlled by the analyst, e.g. ordinal IDs reflect an ordering which must be preserved. Within limits, these IDs may be used outside of the system. For both of these reasons, arbitrary ID attributes require instance data. I really must finish writing up the technical note on arbitrary IDs in OOA10!

Mathematically dependent attributes can be calculated in many different ways. The simplest is on demand which doesn't require instance data. However, a minimum duration between recalculations can also be used by the analyst to restrict how often resource intensive calculations are performed. Presentation data rarely needs to be calculated more than once per second. We may also want to write calculation code which uses previous values to optimize the current iteration (verifying that the previous value is still current may be very fast and worth the effort). These kinds of analysis optimization are difficult to automate at present but should be used sparingly. None of these reasons require a current value to be persisted long-term. However, they do present a need for instance data at some point.

Referential and/or polymorphic attributes have no instance data since they are calculated on demand which generally isn't often since their main purpose in life is to ensure the model is formalized. Composed and mathematically dependent relationships also have no instance data since they are also calculated on demand.

Executable populations extend simple populations with Event Destination Instances, Event Instances, Event Data Item Instances, Operation Instances and Input Parameter Instances. It also defines Threads and Thread Allocations allowing concurrent processing resources to be allocated. The population dependent values that can be used in executable populations are object, event or operation instance values. Return coordinate and transfer vector values can't be used.

Simulations are started by generating an event or invoking an operation. An executable population allows us to define a set of triggers which can be run. It also allows us to define a thread allocation policy which is the minimum information required to execute a realistic concurrent simulation. A default mapping to multiple threads for concurrent simulation purposes is not useful in my view. If you aren't interested in defining a thread allocation policy then use a single thread. I should point out that some systems may require a minimum number of threads to avoid deadlock, e.g. invoking a synchronous service across a bridge will generally block a thread.

Runtime populations extend executable populations with Generated Event Instances (specifying whether delayed and/or recurring), Invoked Operation Instances, Output Parameter Instances and Return Communication Instances (allowing us to track return coordinate and transfer vector returns).

Generated event instances are queued on threads as determined by the thread allocation policy and are consumed as determined by OOA policy. Delayed events block the stream of events between a source/target pair of event destinations (key OOA policy is to ensure sequential processing of events between source/target pair). Recurring events are re-queued after they are consumed allowing heartbeats to be implemented. However, re-queued events may not stop a simulation from completing.

Invoked operation instances are logically pushed on to threads as invoked and pulled off when invocation completes. However, these instances may persist for various reasons, e.g. logging. A thread will also block after invoking a bridging operation mapped to a synchronous service awaiting a synchronous return operation with the correct return coordinate. A thread can also block for other reasons, e.g. awaiting input/output.

Return communication instances allow us to track how timely and often returns occur. Return coordinates must have a single timely return since a thread is waiting for the results. If a timely return does not occur then the system may generate a default return and any later return would then be flagged as an error. Transfer vectors are more flexible as determined by the analyst. They may be conditional or have a multiplicity of many. However, if not conditional then a default initial return may be generated if a time constraint has been specified. Whether any later return is flagged as an error would then depend on whether multiple returns are allowed.

Once I finish tidying up the Simulation subsystem then I will update the OIM on the website. I also need to ensure I have a clean workable design for representing runtime models in OOA Tool 2 based on this work. I also want to be able to generate Thread of Control Charts (and Sequence Diagrams for Executable UML) from runtime populations on completion.

No comments: