int IMessageController.BroadcastToWire(SendBroadcastMemory message) { if (this.IsAlive) return CastTargetController.BroadcastToWire(message); else return 0; }
int IMessageController.BroadcastToWire(SendBroadcastMemory message) { if (this.IsAlive) { return(CastTargetController.BroadcastToWire(message)); } else { return(0); } }
private void HandleReadDelete(string contentLocation,string eTag, List<int> senders, List<int> responsePath ) { // handle proxy messages if (contentLocation.StartsWith(PROXY_PREFIX + "/")) { contentLocation = contentLocation.Substring(PROXYPREFIX_REMOVE); if (!keysToListen.IsSubscribed(contentLocation)) { keysToListen.AddSubscription(contentLocation, SubscriptionInitiator.AutoProxyKey); } } // read ResponseAction status = ReadDelete(contentLocation, eTag, new List<int>(senders)); if (status == ResponseAction.ForwardToAll) { //conflict happened in data somewhere // return new data to sender senders.Clear(); } if (status != ResponseAction.DoNotForward) { // send a notification of deleted content immediately DataEntry entry = P2PDictionary.GetEntry(this.data, this.dataLock, contentLocation); System.Diagnostics.Debug.Assert(entry != null); // add to wire to send out senders.Add(this.local_uid);// add my sender to the packet SendBroadcastMemory sendMsg = new SendBroadcastMemory(entry.key, senders); WriteMethodDeleted(sendMsg.MemBuffer, contentLocation, senders, responsePath, entry.lastOwnerID, entry.lastOwnerRevision); controller.BroadcastToWire(sendMsg); } if (responsePath != null) { // well, i still have to send out this message because there is a path requested to follow DataEntry entry = P2PDictionary.GetEntry(this.data, this.dataLock, contentLocation); System.Diagnostics.Debug.Assert(entry != null); SendMemoryToPeer sendMsg = new SendMemoryToPeer(entry.key, responsePath); senders.Add(this.local_uid);// add my sender to the packet WriteMethodDeleted(sendMsg.MemBuffer, PROXY_PREFIX + contentLocation, senders, responsePath, entry.lastOwnerID, entry.lastOwnerRevision); } }
/// <summary> /// TODO: add in some code to reduce round-trips to simple data types /// </summary> /// <param name="reader">File to read</param> /// <param name="sentFromList">Sent from list</param> /// <param name="getEntriesFromSender">This function fills in a list of entries that need to be requested from the sender</param> /// <param name="addEntriesToSender">These are entries that the sender does not know about</param> /// <seealso cref="ReadHeadStub"/> private void ReadDictionaryTextFile(StreamReader reader, List<int> sentFromList, List<DataHeader> getEntriesFromSender, List<SendMemoryToPeer> addEntriesToSender) { // 0 - key name // 1 - owner // 2 - revision // 3 - rw flag // 4 - MIME type // WriteDebug(this.local_uid + " ReadDictionaryTextFile"); string nsLine = reader.ReadLine(); string[] nsLineParts = nsLine.Split('\t'); System.Diagnostics.Debug.Assert(nsLineParts[0] == DATA_NAMESPACE + "/"); // if the owner of the dictionary is the same as myself, skip reading the changes if (nsLineParts[1] == this.local_uid.ToString()) { throw new NotSupportedException("ReadDictionaryTextFile cannot read itself");// i want to see if this actually can happen (only when multiple connections happen on the same server) } int itemCount = int.Parse(nsLineParts[4]); // count of all the items in the dictionary List<DataEntry> entriesCovered = new List<DataEntry>(itemCount + this.data.Count); for (int i = 0; i < itemCount; i++) { nsLine = reader.ReadLine(); nsLineParts = nsLine.Split('\t'); //WriteDebug(nsLine); DataHeader getEntry = null; SendMemoryToPeer addEntryToSender = null; ETag tag = new ETag(int.Parse(nsLineParts[1]), int.Parse(nsLineParts[2])); // this entry is used only to call ReadMimeSimpleData DataEntry fakeEntry = new DataEntry("/fake", tag, new List<int>(0)); fakeEntry.ReadMimeSimpleData(nsLineParts[4]); dataLock.EnterReadLock(); try { if (this.data.ContainsKey(nsLineParts[0])) { entriesCovered.Add(this.data[nsLineParts[0]]); } } finally { dataLock.ExitReadLock(); } // the dictionary does not report the current sender so let's tack it on List<int> listOfSenders = new List<int>(GetArrayOf(nsLineParts[5])); if (!listOfSenders.Contains(this.remote_uid)) listOfSenders.Add(this.remote_uid); ResponseAction action = ReadDataStub(nsLineParts[0], fakeEntry.GetMime(), nsLineParts[1] + "." + nsLineParts[2], new List<int>( listOfSenders), out getEntry, out addEntryToSender); if (getEntry != null) { getEntriesFromSender.Add(getEntry); } if (addEntryToSender != null) { addEntriesToSender.Add(addEntryToSender); } if (action == ResponseAction.ForwardToAll) { listOfSenders.Clear(); } if (action != ResponseAction.DoNotForward) { DataEntry get = P2PDictionary.GetEntry( this.data, this.dataLock, nsLineParts[0]); System.Diagnostics.Debug.Assert(get != null); listOfSenders.Add(this.local_uid); SendBroadcastMemory msg = new SendBroadcastMemory(get.key , listOfSenders); WriteMethodPush(get.key, listOfSenders, null, 0, get.GetMime(), get.GetETag(), get.IsEmpty, false, msg.MemBuffer); this.controller.BroadcastToWire(msg); } } // now check to see which dictionary entries that the sender does not have; i'll send my entries to the caller this.dataLock.EnterWriteLock(); try { foreach (KeyValuePair<string, DataEntry> senderDoesNotHave in this.data.SkipWhile(x => entriesCovered.Contains(x.Value))) { DataEntry get = senderDoesNotHave.Value; // i know about something that the sender does not know SendMemoryToPeer mem = new SendMemoryToPeer(get.key, sentFromList); WriteMethodPush(get.key, GetListOfThisLocalID(), null, 0, get.GetMime(), get.GetETag(), get.IsEmpty, false, mem.MemBuffer); addEntriesToSender.Add(mem); } } finally { this.dataLock.ExitWriteLock();} }
private void HandleReadPut(string contentLocation, string contentType, byte[] readData, string eTag, List<int> senders, List<int> responsePath) { // process the packet if (contentLocation == DATA_NAMESPACE) { List<DataHeader> missingData = new List<DataHeader>(); List<SendMemoryToPeer> sendBack = new List<SendMemoryToPeer>(); ReadDictionaryTextFile(new StreamReader(new MemoryStream(readData)), new List<int>(senders), missingData, sendBack); // and then update my copy of the dictionary controller.PullFromPeer(missingData); // and update the sender's dictionary controller.SendToPeer(sendBack); } else { if (contentLocation.StartsWith(PROXY_PREFIX + "/")) { // this is a pushed message from a proxy request // so I should subscribe to the key contentLocation = contentLocation.Substring(PROXYPREFIX_REMOVE); if (!keysToListen.IsSubscribed(contentLocation)) { keysToListen.AddSubscription(contentLocation, SubscriptionInitiator.AutoProxyKey); } } ResponseAction status = ReadData(contentLocation, eTag, contentType, new List<int>(senders), readData); // data propagation for following a proxy if (responsePath != null) { List<int> followPath = new List<int>(responsePath); followPath.Remove(this.remote_uid); // send data along the path senders.Add(this.local_uid); SendMemoryToPeer sendMsg = CreateResponseMessage(contentLocation, PROXY_PREFIX + contentLocation, senders, followPath, responsePath); controller.SendToPeer(sendMsg); } if (status == ResponseAction.ForwardToAll) { //conflict happened in data somewhere // return new data to sender senders.Clear(); } if (status != ResponseAction.DoNotForward) { // add my sender to the packet senders.Add(this.local_uid); // add to wire to send out SendBroadcastMemory sendMsg = new SendBroadcastMemory(contentLocation, senders); DataEntry get = P2PDictionary.GetEntry(this.data, this.dataLock, contentLocation); System.Diagnostics.Debug.Assert(get != null); WriteMethodPush(contentLocation, senders, responsePath, 0, get.GetMime(), get.GetETag(), get.IsDeleted, false, sendMsg.MemBuffer); //Response(verb, contentLocation, senders, this.data[contentLocation], sendMsg.MemBuffer, false); controller.BroadcastToWire(sendMsg); } } }
private void HandleReadPush(string contentLocation, string contentType, string eTag, List<int> senders, int lastSender, List<int> responsePath) { ETag tag = ReadETag(eTag); if (contentLocation == DATA_NAMESPACE) { //// tell others that a new dictionary entered //// add to wire to send out //SendMemory sendMsg = new SendMemory(senders); //ResponseDictionary(verb, sendMsg.MemBuffer, senders, false); //controller.BroadcastToWire(sendMsg); // don't forward message because the GET method call will do it // let me update my model first by // requesting to pull data from the other side // before sending out a HEAD DataHeader hdr = new DataHeader(contentLocation, tag, lastSender); controller.PullFromPeer(hdr); } else { if (contentLocation.StartsWith(PROXY_PREFIX + "/")) { // this is a pushed message from a proxy request // so I should subscribe to the key contentLocation = contentLocation.Substring(PROXYPREFIX_REMOVE); throw new NotImplementedException(); } DataHeader getEntryFromSender; SendMemoryToPeer addEntryToSender; ResponseAction action = ReadDataStub(contentLocation, contentType, eTag, new List<int>(senders), out getEntryFromSender, out addEntryToSender); if (action == ResponseAction.ForwardToAll) { senders.Clear(); } if (action != ResponseAction.DoNotForward) { // forward a HEAD message (because we didn't do it when we got a 200/HEAD notification) DataEntry get = P2PDictionary.GetEntry(this.data, this.dataLock, contentLocation); System.Diagnostics.Debug.Assert(get != null); senders.Add(this.local_uid); SendBroadcastMemory sendMsg = new SendBroadcastMemory(contentLocation, senders); WriteMethodPush(contentLocation, senders, responsePath, 0, get.GetMime(), get.GetETag(), get.IsDeleted, false, sendMsg.MemBuffer); controller.BroadcastToWire(sendMsg); } if (getEntryFromSender != null) { // and get data from the caller controller.PullFromPeer(getEntryFromSender); } if (addEntryToSender != null) { // send any updates to the peer controller.SendToPeer(addEntryToSender); } } }