/// <summary> /// Constructor /// </summary> /// <param name="dest">Destination of the message</param> /// <param name="src">Source of the message</param> /// <param name="buf">Byte buffer of payload associated with the message</param> public Message(Address dest, Address src, byte[] buf) { dest_addr = dest; src_addr = src; this.buf = buf; headers = new PropertyCollection(); }
/// <remarks> /// If the member already exists then the member will /// not be added to the membership /// </remarks> /// <summary> /// Adds a new member to this membership. /// </summary> /// <param name="new_member"></param> public void add(Address new_member) { if(new_member != null && !members.Contains(new_member)) { members.Add(new_member); } }
/// <summary> /// Returns true, if this view contains a certain member /// </summary> /// <param name="mbr">The address of the member</param> /// <returns>True, if this view contains a certain member</returns> public bool containsMember( Address mbr ) { if ( mbr == null || members == null ) { return false; } return members.Contains(mbr); }
/// <summary> /// Constructor /// </summary> /// <param name="dest">Destination of the message</param> /// <param name="src">Source of the message</param> /// <param name="obj">Serialisable payload OR array of <c>Message</c>s</param> public Message(Address dest, Address src, Object obj) { dest_addr = dest; src_addr = src; headers = new PropertyCollection(); if(obj!=null) { if(obj is Array) setMessageArray((Array)obj); else if(obj.GetType().IsSerializable) setObject(obj); else throw new Exception("Message can only contain an Array of messages or a ISerializable object"); } }
/// <summary> /// Adds a member into the Digest. /// </summary> /// <param name="sender">Address of new member to add</param> /// <param name="low_seqno">Lowest Sequence num received from this member</param> /// <param name="high_seqno">Highest Sequence num received from this member</param> public void add(Address sender, long low_seqno, long high_seqno) { if(index >= senders.Length) { if(Trace.trace) Trace.error("Digest.add()", "index " + index + " out of bounds, please create new Digest if you want more members !"); return; } if(sender == null) { if(Trace.trace) Trace.error("Digest.add()", "sender is null, will not add it !"); return; } senders[index]=sender; low_seqnos[index]=low_seqno; high_seqnos[index]=high_seqno; high_seqnos_seen[index]=-1; index++; }
/// <summary> /// Sets the highest seen sequence number /// </summary> /// <param name="sender">Member to set the highest seen seq number for</param> /// <param name="high_seqno_seen">New highest seen seq number</param> public void setHighSeqnoSeenAt(Address sender, long high_seqno_seen) { int index=getIndex(sender); if(index < 0) return; else setHighSeqnoSeenAt(index, high_seqno_seen); }
/** * Similar to add(), but if the sender already exists, its seqnos will be modified (no new entry) as follows: * <ol> * <li>this.low_seqno=min(this.low_seqno, low_seqno) * <li>this.high_seqno=max(this.high_seqno, high_seqno) * <li>this.high_seqno_seen=max(this.high_seqno_seen, high_seqno_seen) * </ol> * If the sender doesn not exist, a new entry will be added (provided there is enough space) */ /// <remarks> /// Similar to add(), but if the sender already exists, its seqnos will be modified (no new entry) as follows: /// <list> /// <item>this.low_seqno=min(this.low_seqno, low_seqno)</item> /// <item>this.high_seqno=max(this.high_seqno, high_seqno)</item> /// <item>this.high_seqno_seen=max(this.high_seqno_seen, high_seqno_seen)</item> /// </list> /// If the sender doesn not exist, a new entry will be added (provided there is enough space) /// </remarks> /// <summary> /// Merge member into Digest. Also called from <c>merge(Digest)</c>. /// </summary> /// <param name="sender">Member to merge into Digest</param> /// <param name="low_seqno">Lowest sequence number associated with this member</param> /// <param name="high_seqno">Highest sequence number associated with this member</param> /// <param name="high_seqno_seen">Highest sequence number seen associated with this member</param> public void merge(Address sender, long low_seqno, long high_seqno, long high_seqno_seen) { int index; long my_low_seqno, my_high_seqno, my_high_seqno_seen; if(sender == null) { if(Trace.trace) Trace.error("Digest.merge()", "sender == null"); return; } index=getIndex(sender); if(index == -1) { add(sender, low_seqno, high_seqno, high_seqno_seen); return; } my_low_seqno=lowSeqnoAt(index); my_high_seqno=highSeqnoAt(index); my_high_seqno_seen=highSeqnoSeenAt(index); if(low_seqno < my_low_seqno) setLowSeqnoAt(index, low_seqno); if(high_seqno > my_high_seqno) setHighSeqnoAt(index, high_seqno); if(high_seqno_seen > my_high_seqno_seen) setHighSeqnoSeenAt(index, high_seqno_seen); }
/// <summary> /// Increment the sender's high_seqno by 1 /// </summary> /// <param name="sender">Member to increment</param> public void incrementHighSeqno(Address sender) { if(sender == null) return; for(int i=0; i < senders.Length; i++) { if(senders[i] != null && senders[i].Equals(sender)) { high_seqnos[i]=high_seqnos[i]+1; break; } } }
/// <remarks> /// Creates a ViewID with the coordinator address and the given Lamport timestamp. /// </remarks> /// <summary> /// Constructor /// </summary> /// <param name="coord_addr">The address of the member that issued this view</param> /// <param name="id">The Lamport timestamp of the view</param> public ViewId(Address coord_addr, long id) { this.coord_addr=coord_addr; this.id=id; }
/// <summary> /// Called by the ProtocolSinkStack when messages are recevied. /// </summary> /// <param name="evt">Event that has been received.</param> public void up(Event evt) { int type=evt.Type; Message msg; /*if the queue is not available, there is no point in *processing the message at all*/ if(mq == null) { if(Trace.trace) Trace.error("GroupChannel.up()", "message queue is null"); return; } switch(type) { case Event.MSG: msg=(Message)evt.Arg; if(!receive_local_msgs) { // discard local messages (sent by myself to me) if(local_addr != null && msg.Source != null) if(local_addr.Equals(msg.Source)) return; } break; case Event.VIEW_CHANGE: my_view=(View)evt.Arg; if(!receive_views) // discard if client has not set receving views to on return; break; case Event.SUSPECT: if(!receive_suspects) return; break; case Event.CONNECT_OK: lock(connect_mutex) { Monitor.Pulse(connect_mutex); } break; case Event.DISCONNECT_OK: lock(disconnect_mutex) { Monitor.Pulse(disconnect_mutex); } break; case Event.SET_LOCAL_ADDRESS: local_addr=(Address)evt.Arg; break; case Event.EXIT: handleExit(evt); return; // no need to pass event up; already done in handleExit() default: break; } // If UpHandler is installed, pass all events to it and return (UpHandler is e.g. a building block) if(up_handler != null) { up_handler.up(evt); return; } if(type == Event.MSG || type == Event.VIEW_CHANGE || type == Event.SUSPECT || type == Event.EXIT) //type == Event.GET_APPLSTATE || type == Event.BLOCK { try { mq.Add(evt); } catch(Exception e) { if(Trace.trace) Trace.error("GroupChannel.up()", "exception: " + e); } } }
/// <summary> /// Removes the specified member /// </summary> /// <param name="old_member">Member that has left the group</param> public void remove(Address old_member) { if(old_member != null) { members.Remove(old_member); } }
/// <summary> /// Returns true if the provided member belongs to this membership /// </summary> /// <param name="member">Member to check</param> /// <returns>True if the provided member belongs to this membership, otherwise false</returns> public bool contains(Address member) { if(member == null) return false; return members.Contains(member); }
/// <summary> /// Constructor /// </summary> /// <param name="creator">The creator of this view</param> /// <param name="id">The lamport timestamp of this view</param> /// <param name="members">Contains a list of all the members in the view, can be empty but not null.</param> public View(Address creator, long id, ArrayList members) : this(new ViewId(creator, id), members) { }
/// <summary> /// Processes <c>Events</c> traveling up the stack /// </summary> /// <param name="evt">The Event to be processed</param> public override void up(Event evt) { Message msg; double r; if (evt.Type == Event.SET_LOCAL_ADDRESS) localAddress = (Address) evt.Arg; if (evt.Type == Event.MSG) { msg = (Message) evt.Arg; if (probUp > 0) { r = (double)((double)random.Next(100)/(double)100); if (r < probUp) { if (excludeItself && msg.Source.Equals(localAddress)) { if (Trace.trace) Trace.info("DISCARD.up()", "excluding itself"); } else { if (Trace.trace) Trace.info("DISCARD.up()", "dropping message"); return; } } } } passUp(evt); }
/// <summary> /// Constructor: used for deserialization /// </summary> /// <param name="info">Standard <c>SerializationInfo</c> object</param> /// <param name="ctxt">Standard <c>StreamingContext</c> object</param> public Message(SerializationInfo info, StreamingContext ctxt) { bool b_dest_addr = info.GetBoolean("b_dest_addr"); if (b_dest_addr) dest_addr = (Address)info.GetValue("dest_addr",typeof(object)); bool b_src_addr = info.GetBoolean("b_src_addr"); if (b_src_addr) src_addr = (Address)info.GetValue("src_addr",typeof(object)); int bufferLength = info.GetInt32("bufferLength"); if (bufferLength > 0) { buf = new byte[bufferLength]; for(int i = 0; i< bufferLength;i++) { buf[i] = info.GetByte(i.ToString()); } } String strHeaders = info.GetString("strHeaders"); headers = new PropertyCollection(); if (String.Compare(strHeaders,"NULL")!=0) { String[] headerArray = strHeaders.Split(':'); for(int j = 0;j<headerArray.Length;j++) { headers.Add(headerArray[j],info.GetValue(headerArray[j],typeof(object))); } } }
public void suspect(Address suspected_mbr) { }
public void channelReconnected(Address addr) { if (!closing) txtMsgsReceived.AppendText("-=-=-=-=-" + "Channel is Reconnected!" + "-=-=-=-=-" + "\n"); }
/// <summary> /// Checks if a member is in the Digest /// </summary> /// <param name="sender">Member to check</param> /// <returns>True if the message is in the Digest</returns> public bool contains(Address sender) { return getIndex(sender) != -1; }
/// <remarks> /// Creates a ViewID with the coordinator address and a Lamport timestamp of 0. /// </remarks> /// <summary> /// Constructor /// </summary> /// <param name="coord_addr">The address of the member that issued this view</param> public ViewId(Address coord_addr) { this.coord_addr=coord_addr; }
/// <summary> /// Gets the position of the member in the Digest /// </summary> /// <param name="sender">Member to check</param> /// <returns>Position of member</returns> public int getIndex(Address sender) { int ret=-1; if(sender == null) return ret; for(int i=0; i < senders.Length; i++) if(sender.Equals(senders[i])) return i; return ret; }
/// <summary> /// Processes <c>Events</c> traveling up the stack /// </summary> /// <param name="evt">The Event to be processed</param> public override void up(Event evt) { switch(evt.Type) { case Event.SET_LOCAL_ADDRESS: localAddress = (Address) evt.Arg; localStamp = new VectorTimeStamp(localAddress); delayQueue = new ArrayList(); break; case Event.VIEW_CHANGE: ArrayList newViewMembers = ((View) evt.Arg).getMembers(); localStamp.merge((ArrayList) newViewMembers.Clone()); localStamp.reset(); break; case Event.MSG: Message msg = (Message)evt.Arg; Header hdr = msg.getHeader(getName()); //Check that the correct header is available if(hdr == null || !(hdr is CausalHeader)) { if(Trace.trace) Trace.error("Causal.up()","No Causal Header Found!"); passUp(evt); return; } CausalHeader cHdr = (CausalHeader)hdr; //Pass message up if it is causually next String diag = ""; bool next = localStamp.causallyNext(cHdr.VectorTime, out diag); //passUp(new Event(Event.MSG, new Message(null,localAddress,diag))); if(Trace.trace) Trace.info("CAUSAL.up()", diag + "Causally Next = " + next); if(next) { if(Trace.trace) Trace.info("CAUSAL.up()","Message received in sequence."); passUp(evt); localStamp.max(cHdr.VectorTime); } else //Else add to the delayed queue { if(Trace.trace) Trace.warn("CAUSAL.up()","Message received out of sequence."); cHdr.VectorTime.AssosicatedMessage = msg; addToQueue(cHdr.VectorTime); } //Check the delayed queue removing all items that can be passed up TransportableVectorTimeStamp queuedVector = null; while ((delayQueue.Count > 0) && localStamp.causallyNext((queuedVector = (TransportableVectorTimeStamp)delayQueue[0]), out diag)) { delayQueue.Remove(queuedVector); passUp(new Event(Event.MSG, queuedVector.AssosicatedMessage)); localStamp.max(queuedVector); } return; } passUp(evt); }
/// <summary> /// Gets the highest seen sequence number /// </summary> /// <param name="sender">Member that the highest seen sequence number is required for</param> /// <returns>Highest seen sequence number</returns> public long highSeqnoSeenAt(Address sender) { long ret=-1; int index; if(sender == null) return ret; index=getIndex(sender); if(index == -1) return ret; else return high_seqnos_seen[index]; }