• No se han encontrado resultados

6. RESULTADOS Y ANÁLISIS

6.1. OBSERVATORIO REGIONAL DE CAMBIO CLIMÁTICO DE ANTIOQUIA –

6.1.4. ESTRUCTURA ORGANIZACIONAL

6.1.4.3 EQUIPO TÉCNICO

The following example is provided which may serve as a template for writing a complete and correct component. Essentially one must override one method, process(), and may override six other methods, reset(), duplicate(), info()

and _start()/_stop()/_resume() in a component. Component Template:

1 import drcl.comp.*;

2 import drcl.comp.Port;

3 4 /**

5 * Template for writing a component.

6 */

7 public class ComponentTemplate extends drcl.comp.Component

8 implements drcl.comp.ActiveComponent 9 {

10 // The fields here are simply defined to demonstrate how

11 // methods in this template are used.

12 int x; 13 Port outPort; 14 15 /** 16 * Constructor. 17 */ 18 public ComponentTemplate() 19 { 20 super(); 21 } 22 23 /** 24 * Constructor. 25 */

26 public ComponentTemplate(String id_) 27 {

28 super(id_); 29 }

30

31 /**

32 * Invoked when data_ arrives at this component at the inPort_

33 * port. */

34 protected void process(Object data_, Port inPort_) 35 {

36 // Put codes here for handling the incoming data.

37 outPort_.doSending(data_); 38 }

39 } 40 /**

41 * Resets this component to the initial state to use anew.

42 * Must call super.reset() in the beginning.

43 */

44 public void reset() 45 {

46 super.reset(); // Let super class reset its fields.

47 x = 0; // Reset the fields defined in this class.

48 } 49 /**

50 * Copies the content from the source_ to this component.

51 * Must call super.duplicate() in the beginning.

52 */

53 public void duplicate(Object source_) 54 {

55 super.duplicate(source_); // Let super class copy its fields.

56 ComponentTemplate that_ = (ComponentTemplate)source_;

57 x = that_.x; // Duplicate the fields defined in

58 // this class.

59 } 60 /**

61 * Invoked when the component is run()ed.

62 */

63 protected void _start() 64 {

65 debug(this + " is starting!"); 66 }

67 /**

68 * Script interface which reveals the internal states of the

69 * component. It is for debugging and demonstration purposes. */

70 public String info() 71 {

72 return "Current count = " + x + "\n"; 73 }

74 /**

75 * Script interface which increments the counter by +1.

76 */

77 public void increment() 78 {

79 x++; 80 }

81 }

Method Overrides

1. A component is triggered by data (process(), line 34). The process()

the component. Specifically, the method is invoked by the system whenever some data arrives at one of the component's ports. As mentioned earlier, the method is executed in a new thread context. It is possible for a component to handle multiple data simultaneously in multiple threads. It is component writer's responsibility to ensure data integrity and synchronization among multiple threads.

2. A component can be reset (reset(), line 44). The reset() method sets

the component to its initial state. It allows the component to be started anew after being executed for some time. To correctly override the method, the subclass must call super.reset(). When recursive calling

of the super.reset() method reaches drcl.comp.Component, the method

resets the ports and the child components in a recursive manner. 3. A component can be duplicated (duplicate(), line 53) The duplicate()

method allows the component to be cloned: clone(). A subclass should

override this method to copy the fields defined in the subclass. When overriding the method, the subclass must call super.duplicate() so

that the super class can copy the fields defined in it. When recursive calling of the super.duplicate() method reaches drcl.comp.Component,

the method duplicates the ports and the child components in a recursive manner, and then connects the child component in the same manner as in the source component. The method originates from the

drcl.ObjectDuplicable interface. It complements the clone mechanism

that exists in the java.lang.Object. The RUV system command cp uses

this method to do the tricks.

4. A component may be started as a data source (_start() line 63) In

addition to being triggered by data that arrive at ports, a component can be started by the run() method. The run() method creates a new

thread and then the thread calls the _start() method of the component.

The run() method also calls the run() method of the child components,

until all the components in the hierarchy are started: _start(). As not

all the components in the hierarchy need to be started: _start(), the drcl.comp.ActiveComponent interface is provided. In the run() process

mentioned above, only when a component implements the interface, a new thread is created which in turn calls the _start() method of the

component.

5. One can get state information of a component during runtime (info()

line 70). For the purpose of online debugging and monitoring, a component should override the info() method to provide useful

Rules of Component Writing

1. Script interface: In addition to the methods discussed above, a component may provide several script interfaces to manipulate the component from the scripting environment (e.g. in a Tcl terminal). However, as viewed from a component, the script interfaces of the other components can not be accessed because by virtue of the loosely coupled component architecture, these interfaces are blocked by ports. As a component is interfaced with ports, it does not know to which components it is connected and cannot readily access the interfaces in other components.

2. Data sent is out of sender's control: When a component sends a piece of data, it does not own the data anymore. This rule is not enforced by the programming language. Programmers must make sure that the component does not operate on data that is already sent. No assumption can be made on the data (e.g. modified or recycled by the receiving component) unless it is clearly stated in the contract.

3. Using wrapped APIs to do thread synchronization: In order to gain better control on threads which process data on a component, wrapped thread synchronization APIs are provided, namely

wait(Object)/notify(Object)/notifyAll() in drcl.comp.Component in

replace of wait()/notify()/notifyAll() in java.lang.Object. The

semantics of thread synchronization are still the same as in Java. Using the SUDPApplication Class

To facilitate programming, several template classes have been provided in J-Sim. To implement an application layer protocol, one can extend an application layer class SUDPApplication that has been designed to take care of

many low-level details. In particular, this class provides a set of methods to send/receive a datagram. Below is a template application layer protocol which extends SUDPApplication.

import drcl.comp.Port; import drcl.comp.Contract;

/**

* Example application class. */

public class Application extends drcl.inet.application.SUDPApplication {

aPacketType packet;

// A packet construction mechanism should be provided

public Application ()

super();

}

// This method is used to send packets(Any kind of object) to the // mentioned node.

sendmsg(packet, 10/*size*/, destinationAddress, destinationPort);

protected void dataArriveAtDownPort(Object data, Port downPort)

{

long peerAddress = getPeerAddress(data);

int peerPort = getPeerPort(data);

aPacketType packet = (aPacketType)getContent(data);

// processing methods should be located here or called from here

}

}

6.5 Network Simulation Framework and Simulation Scenario

Documento similar