By: A. Aarsten, G. Elia, G. Menga
Published in: PLoPD1
Category: Automated Manufacturing, Concurrent Systems
Summary: Patterns and a framework of reusable classes for the design of concurrent, possibly distributed, information systems, with applications in computer-integrated manufacturing.
To cope with complexity, organize system functions in hierarchical, decentralized control modules. Each layer of the hierarchy has modules of control that contain similar classes of functions.
To enhance reusability in a hierarchy of layers of control: (1) Don't allow two modules in the same layer to communicate directly. (2) When a client sends a message to a server, it should be done explicitly, in caller/provider fashion. (3) A server should respond by sending events through a broadcast/listener mechanism.
In a complex system, control modules perform services concurrently, and concurrency assumes different scales of granularity. Represent fine-grained activities as event-driven, atomic actions that access sequential objects. Let medium-grained activities run in a thread of control to share blocking objects. Large-grained activities are separate active objects.
Communication through events can be intraservice, generating a small-grained concurrency, or interservice, creating a larger-grained concurrency. Use the broadcast/listening mechanism to raise and listen to events.
Services of a control module must wait for a condition to occur or for data to be transferred before they can perform an action concurrently with others. Blocking objects can solve this problem. Define an abstract class Condition to define any blocking object. Timers, semaphores, event handlers, and shared queues can be derived by inheritance or encapsulation.
Category: Automated Manufacturing, Concurrent Systems, Event-Driven Systems
Control modules must provide services concurrently; therefore provide a common representation at different levels of the hierarchy for standardization purposes, and encapsulate resources and the services that manipulate them. Use a Client/Server/Service model, with two classes: Service and Server. Service encapsulates a thread of execution and can have internal data. Server defines the common characteristics of all active objects.
Control modules manage different pools of shared resources and can offer different kinds of services. Assuming a Server base class: (1) Identify resources the control module needs. Resources shared by the services of an active object can only be blocking objects or other active objects. (2) Identify the different services. Specify their behavior in terms of FSMs extended by sequential objects. (3) Use a graphical notation and SDL to specify service behavior. (4) Define a doService method as a switch statement.
Control modules offer different kinds of services. Use an Interface object to access each server.
To ensure a seamless evolution from simulation to final implementation, maintain two versions of each object: the prototype and the reality object. When moving from simulation to reality, replace the prototype object with the reality object. Ensure consistent transition by having the implementations inherit from a common base class that defines their interface. See From Prototype to Reality
Divide distributed objects into two parts: an interface proxy and the implementation. In the original system, replace objects that have been moved to other nodes with proxy objects to forward requests to the remote object they represent. On the remote node, add support for listening for requests and forwarding them to the correct object.
Category: Automated Manufacturing, Distributed Systems