• 沒有找到結果。

Implementation of the Component Framework

2. Related Work

3.3 Implementation of the Component Framework

3.3.1 Safe Reconfiguration Point

Safe reconfiguration point is a short period in which the protocol stack can be dynamically reconfigured without inconsistent results. It is necessary because the threads other than the reconfiguration thread can also reside in the component framework, including a thread owned by the component framework that handles incoming messages, one or multiple threads owned by the user application that handle outgoing messages, and a thread owned by the component framework that handles timers. Without any restriction, inconsistent results may be produced because these threads are able to invoke the components while they are reconfigured by the reconfiguration thread.

The safe reconfiguration point is governed by the component framework. The exclusive access right is given to the reconfiguration thread when it is about to reconfigure the components. Thus, when the reconfiguration thread is modifying the components, no other thread can invoke them simultaneously. The above behavior is modeled by a Java class that implements a read/write lock. The incoming, outgoing, and timer threads acquire the read lock before invoking the components. The reconfiguration thread acquires the write lock before modifying the components.

3.3.2 Support Libraries

The component framework provides three support libraries to ease the programming. The socket library is for the user application. The socket library is still the standard Java socket library but a custom socket implementation is plugged in. This socket implementation is connected to the component framework rather than the native socket library of the underlying

operating system, and it acquires the read lock before invoking the components. When the user application tries to send a message during the reconfiguration process, the thread of the user application will be temporarily blocked in waiting the read lock since the write lock has been acquired by the reconfiguration management subsystem. When the write lock is released after the reconfiguration, the user application thread can get the read lock and then invoke the components. The message buffer library is a modified version of Jbuf, which was originally developed by the HotLava project (Krupczak et al. 1998). With the message buffer library, the protocol headers can be easily added to and removed from a protocol message. The timer library extends the java.util.TimerTask class of JDK1.4.0. In order to reserve the safe reconfiguration point, it acquires the read lock before invoking the timer handling routines.

3.3.3 Implementation of Reconfiguration Operations

The component framework provides three reconfiguration operations: create, remove, and replace. These operations are provided as a library defined in the operations class. The

reconfiguration program is allowed to use all of the operations while the startup program is only allowed to use the create operation. All the operations are related to the component repository, which is an internal data structure maintained by the reconfiguration management subsystem to keeps track of all component instances. The create operation creates a component instance and registers it with the component repository. It also uses the Java reflection to assign the unique name given by the startup program to the component instance.

The remove operation removes a component instance from the component repository and detaches it from other component instances so that its memory space can be reclaimed by the Java garbage collector.

The replace operation is the most sophisticated one because it is responsible for state

transfer and external reference management. A component replacement involves two component versions. The original version is called the source component and the new version is called the target component because the component state is transferred from the source component instance to the target component instance. Internally, this operation uses several programming techniques, such as Java serialization, serialization stream instrumentation, and Java reflection.

The replace operation consists of eight steps: component finding, object serialization, byte stream instrumentation, object deserialization, reference duplication, reference redirection, user-defined handler invoking, and component registration. The first step searches the component repository to find the source component instance. The second step serializes the source component instance to an in-memory byte stream. This stream temporarily stores the state of the source component instance. The third step, byte stream instrumentation, converts the byte stream from the source component class to the target component class. This step is necessary because multiple versions of a Java class cannot coexist in a Java virtual machine.

Thus, the source and target components must be implemented as separate classes. The deserialization step creates the component instance from the instrumented byte stream. Due to the instrumentation, an instance of the target component rather than the source component is created and its state is inherited from the source component instance. In other words, the target component instance is created with the state of the source component instance.

The fifth step, reference duplication, copies component references from the source component instance to the target component instance, as shown in Figure 1-1d. This step uses Java reflection to inspect each field of the old component instance. If any field refers to a component instance that is stored in the component repository, the value of this field is duplicated to the same field of the target component instance. The above comparison uses the operator == of the Java language, which can test whether two object references refer to the

same object. The sixth step, reference redirection, redirects the component references that originally refer to the source component instance to the target component instance, as shown in Figure 1-1e. This step also utilizes Java reflection and it inspects each field of each component instance other than the source component instance. If any field refers to the source component instance, this field will be redirected to refer the target component instance.

The seventh step, user-defined handler invoking, is executed when the user-defined handler is provided. The final step deregisters the source component instance and registers the target component instance with the component repository.

3.3.4 Implementation of External Interfaces

The component framework is able to communicate with both the user application and network device, as shown in Figure 3-5. The user application communicates with the component framework through the standard Java socket library with a custom socket implementation. For the network device, the component framework is connected with two UNIX FIFOs (Stevens 1999). One is for outgoing data and the other is for incoming data.

When the component invokes the output method of the DeviceDown interface, the

Component Framework

Figure 3-5: External interfaces of the component framework.

Java Socket

component framework sends the payload to the outgoing FIFO. When receiving a message from the incoming FIFO, the component framework invokes the input method of the DeviceUp interface that is implemented by the component. In addition to the incoming and outgoing FIFOs, the component framework is also connected with a reconfiguration FIFO.

When the reconfiguration message is received from the reconfiguration FIFO, the reconfiguration management subsystem will start the reconfiguration process.

相關文件