P2P Simulation with PeerSim 1 Introduction The aim of this tutorial is to describe you the basic concepts needed to implement simulations of different distributed systems such as telecommunication networks (Computer Networks, Cellular Networks, Wireless sensor networks, etc) and network applications (P2P networks, Massively Multiplayer Online Games, Distributed Online Social Networks, Protocols, etc). The most of these systems, such as P2P networks, are extremely large and can contain millions of nodes that join and leave the network continuously. Studing and testing these systems is very difficult because they require a large number of dynamic and scalable resources. Simulator is one of the main method used to experiment with these systems. PeerSim is a single-threaded peer-to-peer simulator that is developed in a modular and scalable way. The modules that compose the simulation are listed in a ASCII configuration file and can be re-used to create quickly the new simulations. PeerSim supports two different simulation models (Figure 2): cycle-based or event-based. The first model is based on a cyclical execution model, where a simulation step is execuded in each cycle. Periodically and sequentially, the control is given to the nodes of the simulation which can perform arbitrary actions (such as call methods of other objects). The second model is based on events (or messages) that can be exchanged between different components of the simulation. Unlike cycle-based model, where nodes communicate directly with each other, the event-based model provides a transport layer that allows nodes to exchange messages. The nodes are scheduled according to the list of pending messages. Moreover, PeerSim allows you to create hybrid simulations, which combine both models (Figure 2(c)). 1 PeerSim is under the GPL license and it is written in the Java language. The building of a new PeerSim application requires access to: • the PeerSim 1.0 package (available at http://sourceforge.net/projects/ PeerSim), or the PeerSim source tree (downloadable from sourceforge CVS server). • the Java Expression Parser version ≥ 2.3.0 (included in the release or available at http://www.singularsys.com/jep/). • the Java compiler for Java version 1.5. To have more information about the PeerSim components and their configuration you can refer to the official documentation of the project. Moreover, it is highly recommended the use of java library OpenCSV (available at opencsv.sourceforge. net/) that allows you to read and write files in a comma separated value format, and the Gnuplot tool (available at www.gnuplot.info/), a utility for plotting graphs stored in CSV files. 2 Components of the Simulator PeerSim is developed to be easily extensible. The components of the simulation are objects that implement a specific java interface provided by PeerSim. Interfaces allow the programmer to create different types of components, each with their behavior. The most important interfaces of the simulator are shown in the Figure 1. The Node interface define a network peer. Each node has a fixed identifier and the same kind of protocols (or protocol stack) which defines its behaviour. The Node interface provides access to the instances of the protocols of the peer. The instances of the nodes and the protocols are created by cloning. That is, only one instance is created using the constructor of the object and all the other instances are cloned from this prototype. Consequently, it is very important to provide an implementation of the cloning method of the protocols and nodes. The CDProtocol interface is a protocol designed to run in the cycle-based model. Protocols are used to define a periodical behaviour of the peer. 2 PeerSim Interfaces Node CDProtocol Control Linkable Figure 1: Interface of the simulator The Linkable interface is a protocol that provides a service to other protocols to access a set of neighbor nodes. The instances of the same linkable class over the nodes define the network topology. PeerSim provides the class peersim.core.IdleProtocol that implements Linkable interface. The only function of this protocol is to serve as a source of neighborhood informazion for other protocol. Also a linkable component may specify its behavior (for example, some gossip protocols need to periodically replace their neighbors with random nodes that are currently available in the system). The Control interface defines an object that can be scheduled for execution at certain points during the simulation. Tipically, Controls that are scheduled periodically during the simulation are named observers because they observe or modify the behaviour of the protocols of the simulation. Controls that are scheduled to run during the initialization phase of the simulation are named Initializers and are used to initialize the internal state of the instances of the protocols running on each nodes. Figure 3 shows the life cycle of a cycle-based simulation. The first step of the simulation reads the configuration file (given as an input parameter) that defines the protocols to experiment. Then, both nodes and protocols are created and initialized. After the initialization phase, by default, every instance of the protocols running on each node is executed once per simulation cycle. The programmer could configure a protocol or a control to run only in some cycles. It is also possible to control the 3 (a) Cycle-based simulation (b) Event-based simulation (c) Hybrid simulation Figure 2: PeerSim simulation models. 4 C1 C2 P C3 C1 C2 P C3 C1 C2 P C3 C4 FINAL init 0 1 2 last Figure 3: Life-cycle of the cycle-based simulation. Controls are labelled with C and protocols with a P. execution order of the components within each cycle. The length of the simulation, i.e. the number of cycles, is specified in the configuration file. The event-based simulation maintains the concept of simulation cycle, but in each cycle are executed only the protocols instances that have some pending events. Events (or messages) are sent by controllers or protocols and they are managed with a handler associated to the protocol that allows to handle a message properly (Figure 2(b)). Messages exchange is simulated by a trasport protocol that provides the communication primitives and allows you to add more realism to the simulation. The package peersim.transport provides several transport protocols. Following, we describe the main components of the PeerSim simulator in more detail through the implementation of a distributed P2P system that computes the aggregated average of a set of values scattered on the nodes. The system can be modeled by an undirected graph G(V, E). Where V is the set of network peers, and E is the set of links between peer. Every peer n of the network is connected to a set of neighbors N (n) in order to form an overlay network. Furthermore, each node n ∈ V has a numeric value vn that is periodically sent to its neighbors via a gossip mechanism. Once a peer n receives the numeric value of its neighbor m ∈ N (n) updates its numeric value vn with the average value (vn + vm )/2. Finally, we can see how the numeric value of each node converges to the average M of all values. 2.1 Nodes and Overlay Network PeerSim provides a simple implementation of a node (peersim.core.GeneralNode). The Node interface defines some methods such as getID() that gets the ID of the node; and the method getProtocol(int procoloId) that gets the instance of the specified protocol running on the node. Class GeneralNode is also able to represent 5 the availability of the nodes in the network (isUp()). The connections between nodes must be modeled through a protocol that implements Linkable interface. The java class NeighborsProtocol defined in Listing 1 implements a simple linkable protocol that is used only to store the neighbor nodes. Linkable interface defines some methods used to manage the set of neighbor nodes. Moreover, the linkable component must implement Protocol interface, used to identify a generic protocol. The clone() method must be redefined properly to make a field-for-field copy/initialization. The constructors of both protocols and controls receive as input parameter the protocol/control prefix used in the configuration file to set up the component. This prefix (as described in the section related to configuration file) can be used to read configuration parameters of the component from the configuration file. Parameters may specify the initial capacity of data structures, configuration values of the component, file names used to store informations, etc. In the configuration file, protocols are identified by a prefix that stars with the keyword protocol. The class constructor of NeighborsProtocol reads the initial capacity of the vector of neighbors, specified through the parameter capacity in the configuration file. Peersim provides the static class peersim.config.Configuration that contains utility methods used to access configuration information. im po rt p e e r s i m . c o n f i g . C o n f i g u r a t i o n ; im po rt p e e r s i m . c o r e . Node ; im po rt j a v a . u t i l . V e c t o r ; /∗ ∗ A p r o t o c o l t h a t s t o r e s l i n k s . ∗/ p u b l i c c l a s s N e i g h b o r s P r o t o c o l implements P r o t o c o l , L i n k a b l e { /∗ ∗ N e i g h b o r s ∗/ p r o t e c t e d Vector<Node> n e i g h b o r s ; /∗ ∗ Parameter f o r i n i t i a l c a p a c i t y o f t h e v e c t o r ∗/ p u b l i c f i n a l s t a t i c S t r i n g PAR INIT CAPACITY=” c a p a c i t y ” ; /∗ ∗ D e f a u l t i n i t i a l c a p a c i t y o f t h e v e c t o r ∗/ p r i v a t e f i n a l s t a t i c i n t d e f a u l t I n i t i a l C a p a c i t y =10; /∗ ∗ I n i t i a l C a p a c i t y ∗/ private static int initialCapacity ; 6 /∗ ∗ C o n s t r u c t o r ∗/ public NeighborsProtocol ( String p r e f i x ) { /∗ ∗ g e t t h e p a r a m e t e r v a l u e from c o n f i g u r a t i o n f i l e . ∗/ i n i t i a l C a p a c i t y=C o n f i g u r a t i o n . g e t I n t ( p r e f i x+” . ”+PAR INIT CAPACITY , defaultInitialCapacity ) ; n e i g h b o r s=new Vector<Node>( i n i t i a l C a p a c i t y ) ; } /∗ ∗ Returns t r u e i f t h e g i v e n node i s a member o f t h e n e i g h b o r s e t . ∗/ p u b l i c b o o l e a n c o n t a i n s ( Node n ) { return neighbors . contains (n) ; } /∗ ∗ Add a n e i g h b o r t o t h e c u r r e n t s e t o f n e i g h b o r s . ∗/ p u b l i c b o o l e a n addNeighbor ( Node n ) { n e i g h b o r s . add ( n ) ; return true ; } /∗ ∗ Returns t h e n e i g h b o r with t h e g i v e n i n d e x . ∗/ p u b l i c Node g e t N e i g h b o r ( i n t i ) { r e t u r n n e i g h b o r s . elementAt ( i ) ; } /∗ ∗ Returns t h e s i z e o f t h e n e i g h b o r l i s t . ∗/ public int degree () { return neighbors . s i z e () ; } /∗ ∗ C l o n e a b l e ∗/ p u b l i c Object c l o n e ( ) { N e i g h b o r s P r o t o c o l np = n u l l ; t r y { np = ( N e i g h b o r s P r o t o c o l ) s u p e r . c l o n e ( ) ; } c a t c h ( C l o n e N o t S u p p o r t e d E x c e p t i o n e ) {} // n e v e r happens np . n e i g h b o r s = new Vector<Node >() ; return ip ; } /∗ ∗ A p o s s i b i l i t y f o r o p t i m i z a t i o n . ∗/ p u b l i c v o i d pack ( ) { } } Listing 1: Methods implemented for Linkable interface. Instances of the NeighborsProtocol on each node are set up through an initializer. PeerSim provides the package peersim.dynamics that contains several classes for initializing a network according to a network model (e.g. random model provided by 7 the class WireKOut or small-world model of Watts and Strogatz provided by the class WireWS) or according to the overlay network G(V,E) stored in a dataset (through the initializer WireFromFile). 2.2 Initializers and controls Classes implementing Control interface could be scheduled for execution at certain points during the simulation. Controls could get the instances of the protocols running on each node, and consequently can modify the simulation, perform periodic actions or observe the state of the system. The classes that implements Control interface must provides the execute method to performs arbitrary modifications or report’s information over the components. By default, It is executed one time in each cycle of the simulation. However, controls can be configured to be run periodically or in specific intervals. A control can terminate the simulation leaving the execute method returning true. Listing 2 specify the control NeighborsObserver that is used to print the neighbors of each node. In order to get instances of linkable protocols running on each node, we should know the identifier of the linkable protocol. The linkable protocol identifier is defined by the parameter protocol, specified in the configuration file. PeerSim models the set of nodes as a collection (through the class peersim.core.Network). In the configuration file, controls are identified by a prefix that stars with the keyword control. The class in Listing 3 defines a controller for printing the numeric value of each node. This value is defined by the instance of the protocol (named AggregatedAverageGossipProtocol) running on the node. The NodeValuesObserver receives as an input parameter (named protocol) the protocol to be observed. The execution order of controllers can be specified in the configuration file. im po rt im po rt im po rt im po rt peersim . peersim . peersim . peersim . config . Configuration ; core . Control ; c o r e . Network ; c o r e . Node ; /∗ ∗ A c o n t r o l t h a t o b s e r v e s t h e n e i g h b o r h o o d o f t h e nodes . ∗/ p u b l i c c l a s s N e i g h b o r s O b s e r v e r implements C o n t r o l { 8 /∗ ∗ Parameter f o r L i n k a b l e p r o t o c o l i d e n t i f i e r . ∗/ p r i v a t e s t a t i c f i n a l S t r i n g PAR PROT = ” p r o t o c o l ” ; /∗ ∗ P r o t o c o l i d e n t i f i e r ; o b t a i n e d from c o n f i g p r o p e r t y { @ l i n k #PAR PROT} . ∗/ p r i v a t e s t a t i c i n t pid ; public NeighborsObserver ( String p r e f i x ) { // g e t i d e n t i f i e r o f l i n k a b l e p r o t o c o l p i d=C o n f i g u r a t i o n . g e t P i d ( p r e f i x+” . ”+PAR PROT) ; } /∗ ∗ r e t u r n t r u e i f t h e s i m u l a t i o n has t o be s t o p p e d ∗/ public boolean execute ( ) { Node node ; NeighborsProtocol neighbors ; // P r i n t t h e n e i g h b o r s o f each node . f o r ( i n t i =0; i <Network . s i z e ( ) ; i ++){ node= Network . g e t ( i ) ; n e i g h b o r s =( N e i g h b o r s P r o t o c o l ) node . g e t P r o t o c o l ( p i d ) ; System . out . p r i n t l n ( node . getID ( ) ) ; f o r ( i n t n=0;n<n e i g h b o r s . d e g r e e ( ) ; n++){ System . out . p r i n t ( n e i g h b o r s . g e t N e i g h b o r ( n ) . getID ( ) ) ; } System . out . p r i n t l n ( ) ; } return f a l s e ; } } Listing 2: Methods defined by the NeighborsObserver Control. im po rt im po rt im po rt im po rt peersim . peersim . peersim . peersim . config . Configuration ; core . Control ; c o r e . Network ; c o r e . Node ; /∗ ∗ A c o n t r o l l e r t h a t g e t s t h e v a l u e o f each node ∗/ p u b l i c c l a s s NodeValuesObserver implements C o n t r o l { /∗ ∗ P r o t o c o l i d e n t i f i e r o f { @ l i n k A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l } . ∗/ p r i v a t e s t a t i c f i n a l S t r i n g PAR PROT = ” p r o t o c o l ” ; /∗ ∗ P r o t o c o l i d e n t i f i e r ; o b t a i n e d from c o n f i g p r o p e r t y { @ l i n k #PAR PROT} . ∗/ p r i v a t e s t a t i c i n t pid ; /∗ ∗ C o n s t r u c t o r ∗/ p u b l i c NodeValuesObserver ( S t r i n g p r e f i x ) { // g e t i d e n t i f i e r o f l i n k a b l e p r o t o c o l p i d = C o n f i g u r a t i o n . g e t P i d ( p r e f i x + ” . ” + PAR PROT) ; } 9 /∗ ∗ r e t u r n t r u e i f t h e s i m u l a t i o n has t o be s t o p p e d ∗/ public boolean execute ( ) { Node node ; A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l aagp ; // p r i n t s t h e v a l u e o f t h e node f o r ( i n t i =0; i <Network . s i z e ( ) ; i ++){ node=Network . g e t ( i ) ; aagp=( A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l ) node . g e t P r o t o c o l ( p i d ) ; System . out . p r i n t l n ( ”Node ”+node . getID ( )+” v a l u e = ”+aagp . g e t V a l u e ( ) ) ; } return f a l s e ; } } Listing 3: Methods defined by the NodeValuesObserver Control. The initializers are controls executed only once time before the beginning of the simulation. They are identified by a prefix, in the configuration file, that stars with the keyword init. Initializer leads with the configuration of all the protocols of the simulation. Listing 4 defines the initializer of the protocol AggregatedAverageGossipProtocol that contains the numerical value to initialize. The numerical values on the nodes are initialized according to the pseudo-random Gaussian distribution with the mean 0 and the variance 1. Initializers are executed after the creation of the instances of the protocols but before the beginning of the simulation. As for controls, you can change the execution order of initializers from the configuration file. Moreover, components (protocols, controls and initializers) may receive several types of parameters from the configuration file, such as Boolean, Double, Integer, String, Java Class, Object, Protocol Identifier, Long, etc. Such input parameters can be used to specialize the component behaviour. im po rt im po rt im po rt im po rt im po rt j a v a . u t i l . Random ; peersim . c o n f i g . Configuration ; peersim . core . Control ; p e e r s i m . c o r e . Network ; p e e r s i m . c o r e . Node ; /∗ ∗ I n i t i a l i z e s t h e v a l u e o f t h e nodes a c c o r d i n g t o t h e ∗ Gaussian d i s t r i b u t i o n with mean 0 and v a r i a n c e 1 . ∗/ p u b l i c c l a s s I n i t N o d e V a l u e s implements C o n t r o l { /∗ ∗ P r o t o c o l i d e n t i f i e r t o be i n i t i a l i z e d . { @ l i n k A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l } . ∗/ 10 private static f i n a l S t r i n g PAR PROT = ” p r o t o c o l ” ; /∗ ∗ P r o t o c o l i d e n t i f i e r ; o b t a i n e d from c o n f i g p r o p e r t y { @ l i n k #PAR PROT} . ∗/ p r i v a t e s t a t i c i n t pid ; /∗ ∗ C o n s t r u c t o r ∗/ public InitNodeValues ( String p r e f i x ) { // g e t i d e n t i f i e r o f l i n k a b l e p r o t o c o l p i d=C o n f i g u r a t i o n . g e t P i d ( p r e f i x+” . ”+PAR PROT) ; } /∗ ∗ r e t u r n t r u e i f t h e s i m u l a t i o n has t o be s t o p p e d ∗/ public boolean execute ( ) { Random rand=new Random ( System . nanoTime ( ) ) ; Node node ; A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l aagp ; // I n i t i a l i z e t h e numeric v a l u e o f each node . f o r ( i n t i =0; i <Network . s i z e ( ) ; i ++){ node= Network . g e t ( i ) ; aagp=( A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l ) node . g e t P r o t o c o l ( p i d ) ; aagp . s e t V a l u e ( rand . n e x t G a u s s i a n ( ) ) ; } return f a l s e ; } } Listing 4: Methods defined by the Initializer InitNodeValues. 2.3 Cycle and Event based Protocol The java class that implements peersim.cdsim.CDProtocol interface define a cycle based protocols, e.i. protocols with a periodic activity. The java class that implements a cycle-based protocol must provide the method nextCycle(Node, ProtocolId), that define the algorithm of the protocol to be executed periodically. The method nextCycle receives as an input parameter the node that is running the protocol instance and the identifier of the protocol. Listing 5 defines the protocol AggregatedAverageGossipProtocol that computes the aggregated average of a numeric collection. Each instance of the protocol contains the numeric field value initialized by InitNodeValues (defined in Section 2.2). In order to get the neighbors of the node, gossip protocol receives the Linkable protocol identifier as an input parameter (named protocol). The class constructor gets the linkable protocol identifier (the same for each node). The gos11 sip round, defined by method nextCycle, gets a random neighbor of the node and update their numeric value (method update). The instances of the protocol AggregatedAverageGossipProtocol interact directly every with each other through the methods implemented by the class (i.e. without message exchange). Finally, the protocol is equipped with the clone method and the getter and setter for value field. The implemented protocol (Listing 5) can be tested only in a cycle-based simulation where the method nextCycle is scheduled for execution at each cycle. im po rt im po rt im po rt im po rt j a v a . u t i l . Random ; p e e r s i m . cdsim . CDProtocol ; peersim . c o n f i g . Configuration ; p e e r s i m . c o r e . Node ; /∗ ∗ A G o s s i p p r o t o c o l t h a t compute t h e a g g r e g a t e d a v e r a g e ∗ o f a c o l l e c t i o n o f d o u b l e s c a t t e r e d on t h e nodes . ∗/ p u b l i c c l a s s A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l implements CDProtocol , C l o n e a b l e { /∗ ∗ Numeric Value ∗/ p r i v a t e double value ; /∗ ∗ L i n k a b l e p r o t o c o l ∗/ p u b l i c s t a t i c f i n a l S t r i n g PAR PROTOCOL=” l i n k a b l e ” ; /∗ ∗ L i n k a b l e p r o t o c o l i d e n t i f i e r ∗/ public int linkableId ; /∗ ∗ C l a s s c o n s t r u c t o r ∗/ public AggregatedAverageGossipProtocol ( String p r e f i x ) { /∗ ∗ g e t s t h e p r o t o c o l i d e n t i f i e r ∗/ l i n k a b l e I d=C o n f i g u r a t i o n . g e t P i d ( p r e f i x+” . ”+PAR PROTOCOL) ; } /∗ ∗ A g o s s i p c y c l e ∗/ p u b l i c v o i d n e x t C y c l e ( Node node , i n t p i d ) { // g e t s a random n e i g h b o r Random rand=new Random ( System . nanoTime ( ) ) ; N e i g h b o r s P r o t o c o l n e i g h b o r s= ( N e i g h b o r s P r o t o c o l ) node . g e t P r o t o c o l ( l i n k a b l e I d ) ; i f ( n e i g h b o r s . d e g r e e ( ) >0){ update ( n e i g h b o r s . g e t N e i g h b o r ( rand . n e x t I n t ( n e i g h b o r s . d e g r e e ( ) ) ) , p i d ) ; } } /∗ ∗ ∗ Exchange and update t h e v a l u e ∗ @param n e i g h b o r Neighbor o f t h e node 12 ∗ @param p i d I d e n t i f i e r o f { @ l i n k #A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l ( S t r i n g ) } ∗/ p r i v a t e v o i d update ( Node n e i g h b o r , i n t p i d ) { A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l aagp=( A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l ) n e i g h b o r . getProtocol ( pid ) ; d o u b l e mean=(aagp . v a l u e+v a l u e ) / 2 . 0 ; v a l u e=mean ; aagp . v a l u e=mean ; } /∗ ∗ C l o n e a b l e ∗/ public AggregatedAverageGossipProtocol clone () { A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l sn = n u l l ; try { sn = ( A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l ) s u p e r . c l o n e ( ) ; } catch ( CloneNotSupportedException e ) { } // n e v e r happens sn . p r o t o c o l I d=p r o t o c o l I d ; sn . v a l u e=v a l u e ; r e t u r n sn ; } /∗ ∗ G e t t e r s and S e t t e r s ∗/ p u b l i c double getValue ( ) { return value ; } p u b l i c void setValue ( double value ) { t h i s . value = value ; } } Listing 5: A gossip cycle-based protocol that computes the aggregated average of a numeric collection. Listing 6 define the aggredated average gossip protocol for an event-based simulation. An event-based protocol is defined by the peersim.cdsim.EDProtocol interface. Instances of the protocols interacts with each other via message exchanging. The messages are described by the classes in Listing 7 and messages exchange is simulated by a trasport protocol that provides the communication primitives. The package peersim.transport provides several transport protocols that can be used in the simulation. The gossip event-based protocol requires the identifiers of both linkable and transport protocol in order to get a neighbor node and exchange with it the numeric value. The identifier of both protocols linkable and transport can be read from the configu13 Node 0 Node 1 Node N-1 Protocol stack's instances Protocol stack's instances Protocol stack's instances Linkable Linkable Linkable CDProtocol1 CDProtocol1 CDProtocol1 CDProtocol2 CDProtocol2 CDProtocol2 EDProtocol1 EDProtocol1 EDProtocol1 EDProtocol2 EDProtocol2 EDProtocol2 Transport Transport Transport Figure 4: Overview of the protocol stack on the nodes. ration file through the input parameters named linkable and transport (as shown by class constructor in Listing 6). The java class that implements an event-based protocol must provide the method processEvent(node,pid,message), that defines the actions to perform every time a message arrives to the protocol identified by pid, running on node. If the arrived message is the request message (RequestMessage) the node replies with a response message containing its numerical value (ResponseMessage) and then update its local value with the one in the message. If the arrived message is a response message (ResponseMessage), the node updates merely its local value with the one contained in the message. However, each of the node need to periodically execute the gossip round, i.e. gets a neighbor randomly and send to it a request message. We implement this gossip round with a hybrid protocol which combines the features of both cycle and event based simulation. Therefore, the protocol in Listing 6 also implements the interface peersim.cdsim.CDProtocol, and consequently the nextCycle method (that contanis the implementation of the gossip round). The update function that is defined here sends a request message to a random neighbor node. The protocol can be set up (via the configuration file) to periodically execute the nextCycle method. Now we describe the configuration file used to experiment with the protocols defined above. 14 im po rt im po rt im po rt im po rt im po rt im po rt j a v a . u t i l . Random ; p e e r s i m . cdsim . CDProtocol ; peersim . c o n f i g . Configuration ; p e e r s i m . c o r e . Node ; p e e r s i m . edsim . EDProtocol ; peersim . t r a n s p o r t . Transport ; /∗ ∗ A G o s s i p p r o t o c o l t h a t compute t h e ∗/ p u b l i c c l a s s A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l E D implements CDProtocol , EDProtocol , Cloneable { /∗ ∗ Value ∗/ p r i v a t e double value ; /∗ ∗ L i n k a b l e p r o t o c o l ∗/ p u b l i c s t a t i c f i n a l S t r i n g PAR PROTOCOL = ” l i n k a b l e ” ; /∗ ∗ L i n k a b l e p r o t o c o l i d e n t i f i e r ∗/ public int linkableId ; /∗ ∗ T r a n s p o r t p r o t o c o l f o r event−based s i m u l a t i o n ∗/ p u b l i c s t a t i c f i n a l S t r i n g PAR TRASP = ” t r a n s p o r t ” ; /∗ ∗ T r a n s p o r t p r o t o c o l i d e n t i f i e r f o t event−based s i m u l a t i o n ∗/ public int transportId ; /∗ ∗ C l a s s c o n s t r u c t o r ∗/ p u b l i c AggregatedAverageGossipProtocolED ( S t r i n g p r e f i x ) { /∗ ∗ g e t s t h e p r o t o c o l i d e n t i f i e r ∗/ l i n k a b l e I d = C o n f i g u r a t i o n . g e t P i d ( p r e f i x + ” . ” + PAR PROTOCOL) ; t r a n s p o r t I d = C o n f i g u r a t i o n . g e t P i d ( p r e f i x + ” . ” + PAR TRASP) ; } /∗ ∗ Message h a n d l e r ∗/ p u b l i c v o i d p r o c e s s E v e n t ( Node node , i n t pid , O b j e c t message ) { i f ( message i n s t a n c e o f RequestMessage ) { /∗ ∗ Reply with a Response message ∗/ RequestMessage r e q M e s s a g e =( RequestMessage ) message ; T r a n s p o r t t= ( T r a n s p o r t ) node . g e t P r o t o c o l ( t r a n s p o r t I d ) ; ResponseMessage r e s p M e s s a g e=new ResponseMessage ( v a l u e , node ) ; t . send ( node , r e q M e s s a g e . s r c , r e s pM e s s a g e , p i d ) ; v a l u e =( v a l u e+r e q M e s s a g e . v a l u e ) / 2 . 0 ; } e l s e i f ( message i n s t a n c e o f ResponseMessage ) { /∗ ∗ R e c e i v e a Response message ∗/ ResponseMessage r e s p M e s s a g e =( ResponseMessage ) message ; v a l u e =( v a l u e+r e s p M e s s a g e . v a l u e ) / 2 . 0 ; } } /∗ ∗ A g o s s i p c y c l e ∗/ 15 p u b l i c v o i d n e x t C y c l e ( Node node , i n t p i d ) { // g e t s a random n e i g h b o r Random rand = new Random ( System . nanoTime ( ) ) ; N e i g h b o r s P r o t o c o l n e i g h b o r s = ( N e i g h b o r s P r o t o c o l ) node . g e t P r o t o c o l ( l i n k a b l e I d ) ; Node randomNode ; i f ( neighbors . degree ( ) > 0) { randomNode=n e i g h b o r s . g e t N e i g h b o r ( rand . n e x t I n t ( n e i g h b o r s . d e g r e e ( ) ) ) ; update ( node , randomNode , p i d ) ; } } /∗ ∗ ∗ Exchange t h e numeric v a l u e with d e s t . ∗ @param s r c S o u r c e node ∗ @param d e s t D e s t i n a t i o n node ∗ @param p i d I d e n t i f i e r o f t h e p r o t o c o l t a r g e t { @ l i n k AggregatedAverageGossipProtocolED } ∗/ p r i v a t e v o i d update ( Node s r c , Node d e s t , i n t p i d ) { T r a n s p o r t t r a n s p o r t= ( T r a n s p o r t ) s r c . g e t P r o t o c o l ( t r a n s p o r t I d ) ; RequestMessage rMessage=new RequestMessage ( v a l u e , s r c ) ; t r a n s p o r t . send ( s r c , d e s t , rMessage , p i d ) ; } /∗ ∗ C l o n e a b l e ∗/ p u b l i c AggregatedAverageGossipProtocolED c l o n e ( ) { A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l E D sn = n u l l ; try { sn = ( A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l E D ) s u p e r . c l o n e ( ) ; } catch ( CloneNotSupportedException e ) { } // n e v e r happens sn . p r o t o c o l I d = p r o t o c o l I d ; sn . t r a n s p o r t I d=t r a n s p o r t I d ; sn . v a l u e = v a l u e ; r e t u r n sn ; } /∗ ∗ G e t t e r s and S e t t e r s ∗/ p u b l i c double getValue ( ) { return value ; } p u b l i c void setValue ( double value ) { t h i s . value = value ; } } Listing 6: A gossip hybrid-based protocol that computes the aggregated average of a numeric collection. 16 im po rt p e e r s i m . c o r e . Node ; /∗ ∗ A r e q u s t message with a numeric d o u b l e v a l u e and a s o u r c e node ∗/ p u b l i c c l a s s RequestMessage { /∗ ∗ Numeric v a l u e o f t h e node s r c ∗/ p u b l i c double value ; /∗ ∗ S o u r c e node ∗/ p u b l i c Node s r c ; /∗ ∗ C r e a t e a new r e q u e s t message with t h e ∗ s p e c i f i e d numeric v a l u e and s o u r c e node ∗/ p u b l i c RequestMessage ( d o u b l e v a l u e , Node s r c ) { t h i s . v a l u e=v a l u e ; t h i s . s r c=s r c ; } } /∗ ∗ A r e s p o n s e message with a numeric d o u b l e v a l u e and a s o u r c e node ∗/ p u b l i c c l a s s ResponseMessage { /∗ ∗ Numeric v a l u e o f t h e node s r c ∗/ p u b l i c double value ; /∗ ∗ S o u r c e node ∗/ p u b l i c Node s r c ; /∗ ∗ C r e a t e a new r e s p o n s e message with t h e ∗ s p e c i f i e d numeric v a l u e and s o u r c e node ∗/ p u b l i c ResponseMessage ( d o u b l e v a l u e , Node s r c ) { t h i s . s r c=s r c ; t h i s . v a l u e=v a l u e ; } } Listing 7: Messages defined by the AggregatedAverageGossipProtocolED protocol. 2.4 Configuration of the simulation The configuration file defines two types of settings: the global settings of the simulation and the local settings of individual components (such as protocol, control, linkable, transport, etc). The file consists of name-value pairs (according to the representation defined by java.util.Properties), where the lines that begin with the character “#” are interpreted as comment. Listing 8 describes the global properties needed to configure of the simulation. Prop17 erty random.seed specifies the seed of a pseudo-random generator of the simulator used to replicate experiments based on random behavior. Moreover, it defines the number of nodes (network.node) and the number of simulation cycles (simulation.endtime). By default, all components are executed in each cycle. However, it is possible to configure a protocol or control to run only in certain cycles, and it is also possible to control the order of the running of the components within each cycle. In order to be used in the simulation, identification names of both controls and initializers must be specified in the property include.control and include.init. This property also defines the order in which the components are run. The default order is according to alphabetical order of the component names. # PeeSim Simulation random . seed 1234567890 # number of network nodes ( up to 10^6) SIZE 5000 # number of simulation cycles CYCLES 80 network . size SIZE simulation . endtime CYCLES # Class that implements network nodes . network . node GeneralNode # Initializers to use include . init initAvgCD initAvgED netInit in it Sc he dul er Av gE D # Controls to use and order of execution include . control neighObs valueObsCD valueObsED Listing 8: Global properties of the simulation The configuration of the protocols takes place by putting related configuration 18 fragment, that specifies the behavior of the protocol and the required parameters. A component (such as a protocol, control or a initializer) is declared by the following syntax: < protocol | init | control >. string_id [ full_path_ ] classname The full class path is optional because PeerSim can search in its classpath in order to find a class. If multiple classes share the same name (in distinct packages), the full path is needed. The first part of declaration contains the component type (i.e. protocol, control or initializer ), followed by the component name (string id) and the value part that contain the classname for the component. PeerSim relate the names of the protocols (string id) with a numeric index named protocol ID (the same for the entire life of the simulation). This index does not appear in the configuration file, but it is necessary to access protocols during a simulation. The component parameters follows this scheme: < protocol | init | control >. string_id . parameter_name value Parameters can be declared for each component; The key part contains the parameter’s name (parameter name) and the value part is simply the parameter’s value (value) . Listing 11 configures the protocols defined in the previous sections. The prefix protocol defines the protocol. The cycle-based protocols (that define the nextCycle method) are executed periodically as specified in the configuration file by the parameters from, step and until. Parameters from, until and step can be specified for each component (protocols and controls). They select the cycles in which the given component is executed. Parameter step (by default equal to 1) define the elapsed cycles between two subsequent executions of the component. The event-based protocol AggregatedAverageGossipProtocolED uses peersim.transport.UniformRandomTransport, a PeerSim transport protocol that reliably delivers messages with a random delay. 19 # Cycle - based aggregated average gossip protocol protocol . avgCD A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l # Input parameters of the linkable protocol protocol . avgCD . linkable lnk # Hybrid - based aggregated average gossip protocol protocol . avgED A g g r e g a t e d A v e r a g e G o s s i p P r o t o c o l E D # Input parameters of the linkable protocol protocol . avgED . linkable lnk # Input parameters of the transport protocol protocol . avgED . transport tr # How often perform the nextCycle method protocol . avgED . step 3; # Linkable protocol to store neighbors protocol . lnk Neig hborsP rotoco l # Initial capacity of the neighbors list . protocol . lnk . capacity 10 # PeerSim transport protocol protocol . tr U n i f o r m R a n d o m T r a n s p o r t # minimum latency protocol . tr . mindelay 0 # maximum latency protocol . tr . maxdelay 0 Listing 11: Protocol configuration. The prefix control defines a control object, that has to implement the peersim.core.Control interface. Listing 13 shows the controls that are used in the simulation. Control NeighborsObserver (named neighObs) is configured to run only in the first cycle of the simulation. The components valueObsCD and valueObsED print numeric values of the protocols avgCD and avgED. The control NodeValuesObserverED differs from NodeValuesObserver (defined in Listing 3) only by the type of the observed protocol (AggregatedAverageGossipProtocolED). The prefix init defines a initializer object, that has to implement the peersim.core.Control interface. Listing 14 shows the initializers that are used in the simulation. The initializers initAvgCD and initAvgED deal with the initialization of the numeric field of the protocols avgCD and avgED. 20 The network topology is initialized according to the random graph model (through the PeerSim initializer named peersim.dynamics.WireKOut). Nodes are linked randomly to each other to form a random graph having the specified degree (k) parameter. Finally we have the predefined PeerSim initializer: initSchedulerAvgED (implemented by peersim.edsim.CDScheduler). This initializer is used in hybridbased simulation/protocol and allows to schedules periodically the execution of the nextCycle method of the protocol instances in the event driven simulation. In this case, the nextCycle method defined for avgED are executed only once every three cycles (as defined in Listing 11). The simulation can be run invoking the peersim.Simulator class with a configuration file, that contains the above information. java - cp < classpath > peersim . Simulator co nfigur ationF ile . txt # Control to print the neighbors . control . neighObs N eighbo rsObse rver # Input parameters of the linkable protocol control . neighObs . protocol lnk control . neighObs . from 1 control . neighObs . until 2 control . neighObs . step 1 # Control to print the numeric value in avgCD control . valueObsCD No de Va lue sO bs er ve r control . valueObsCD . protocol avgCD # Control to print the numeric value in avgED control . valueObsED N o d e V a l u e s O b s e r v e r E D control . valueObsED . protocol avgED Listing 13: Control configuration. # Control to print the neighbors . init . initAvgCD InitNodeValues # Input parameters of the linkable protocol 21 init . initAvgCD . protocol avgCD # Control to print the neighbors . init . initAvgED InitNodeValuesED # Input parameters of the linkable protocol init . initAvgED . protocol avgED # Event - based aggregated average gossip protocol init . netInit WireKOut # The linkable protocol to operate on init . netInit . protocol lnk # Number of outgoing edges to generate from each node init . netInit . k 5 # Initialize the execution of the cycle based protocol instances in the event driven engine . init . i ni tS ch ed ul er Av gE D CDScheduler init . i ni tS ch ed ul er Av gE D . protocol avgED Listing 14: Initializer configuration. References [1] Gian Paolo Jesi. PeerSim HOWTO: Build a new protocol for the PeerSim 1.0 simulator. [2] Mark Jelasity. A Basic Event Driver Example for PeerSim 1.0. 22
© Copyright 2024