//********************************************************************************************** // ArrivedAtDestination //********************************************************************************************** /// <summary> /// Called by the overlay when ArrivedAtDestination is about to be called for a request message. /// Sets up state to avoid calling ArrivedAtDestination multiple times. /// /// Cuando llega al destino es llamado /// </summary> public void HandleArrivedAtDestination(Message msg) { OverlayRequest request = msg.Payload as OverlayRequest; try { // Get the request's nodeId string id = request.Id; // Look up the request's nodeId in the table. // Note: Normally, an entry for this nodeId will already exist. // But, sometimes during CLB routing, ArrivedAtDestination() is called // without ever calling CheckContinueRouting() at that node. TableEntry entry; if (table.ContainsKey(id)) { // Get the entry for this nodeId entry = (TableEntry)table[id]; } else { // Create a new entry for this nodeId and add it to the table entry = new TableEntry(id, request, msg); lock (sync) { table.Add(id, entry); } } // Start a timer to garbage-collect this table entry if (entry.gcTimer == null) { EntryGCTimer timer = new EntryGCTimer(request); entry.gcTimer = timer; localNode.SetTimer(timer); } // If ArrivedAtDestination has not already been called at this node, call it if (!entry.adCalled) { entry.adCalled = true; request.ArrivedAtDestination(localNode, msg); } } catch (Exception err) { // mandamos este error al nodo que hizo la petición OverlayError replyErrMsg = new OverlayError(request, err); localNode.SendReply(replyErrMsg, msg.Source); throw err; } }
/// <summary> /// Called by a reply message when it arrives at the original source. /// </summary> /// <param name="reply"></param> public void ReceivedReply(OverlayReply reply) { // Get the request's nodeId string id = reply.RequestId; // Look up the request's nodeId in the table. if (table.ContainsKey(id)) { // Get the entry for this nodeId TableEntry entry = (TableEntry)table[id]; if (entry.request == null) { // If there is no request message, this node is not the source } else { OverlayRequest request = entry.request; // calculate duration entry.durationRequest = DateTime.Now.Subtract(entry.insertedTime); // Cancel the pending timer. localNode.CancelTimer(entry.replyTimer); if (request.Async != null) { // todo realizado adecuadamente request.Async.success = true; // comprobamos que nos hayan enviado un error if (reply is OverlayError) { OverlayError overlayErr = (OverlayError)reply; request.Async.success = false; request.Async.exception = overlayErr.GetException(); } else { request.Async.Reply = reply; } // ejecutamos el callback ExecuteCallback(request); } // Remove the entry from the table RemoveEntry(id); } } }