Added util.ExponentialReExpressClosure.js.
diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index 9b1be2a..30d137d 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -425,6 +425,61 @@
}*/
/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * This is the closure class for use in expressInterest to re express with exponential falloff.
+ */
+
+/*
+ * Create a new ExponentialReExpressClosure where upcall responds to UPCALL_INTEREST_TIMED_OUT
+ * by expressing the interest again with double the interestLifetime. If the interesLifetime goes
+ * over maxInterestLifetime, then call callerClosure.upcall with UPCALL_INTEREST_TIMED_OUT.
+ * When upcall is not UPCALL_INTEREST_TIMED_OUT, just call callerClosure.upcall.
+ *
+ * settings is an associative array with the following defaults:
+ * {
+ * maxInterestLifetime: 16000 // milliseconds
+ * }
+ */
+var ExponentialReExpressClosure = function ExponentialReExpressClosure
+ (callerClosure, settings) {
+ // Inherit from Closure.
+ Closure.call(this);
+
+ this.callerClosure = callerClosure;
+ settings = (settings || {});
+ this.maxInterestLifetime = (settings.maxInterestLifetime || 16000);
+};
+
+ExponentialReExpressClosure.prototype.upcall = function(kind, upcallInfo) {
+ try {
+ if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
+ var interestLifetime = upcallInfo.interest.interestLifetime;
+ if (interestLifetime == null)
+ return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, upcallInfo);
+
+ var nextInterestLifetime = interestLifetime * 2;
+ if (nextInterestLifetime > this.maxInterestLifetime)
+ console.log("nextInterestLifetime " + nextInterestLifetime + " > max " +
+ this.maxInterestLifetime + ". Timing out for " + upcallInfo.interest.name.to_uri()); // DEBUG
+ if (nextInterestLifetime > this.maxInterestLifetime)
+ return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, upcallInfo);
+
+ var nextInterest = upcallInfo.interest.clone();
+ nextInterest.interestLifetime = nextInterestLifetime;
+ console.log("Re-express nextInterestLifetime " + nextInterestLifetime +
+ " for " + upcallInfo.interest.name.to_uri()); // DEBUG
+ upcallInfo.ndn.expressInterest(nextInterest.name, this, nextInterest);
+ return Closure.RESULT_OK;
+ }
+ else
+ return this.callerClosure.upcall(kind, upcallInfo);
+ } catch (ex) {
+ console.log("ExponentialReExpressClosure.upcall exception: " + ex);
+ return Closure.RESULT_ERR;
+ }
+};
+/**
* @author: Meki Cheraoui, Jeff Thompson
* See COPYING for copyright and distribution information.
* This class represents a Name as an array of components where each is a byte array.
@@ -1322,7 +1377,9 @@
*/
// _interestLifetime is in milliseconds.
-var Interest = function Interest(_name,_faceInstance,_minSuffixComponents,_maxSuffixComponents,_publisherPublicKeyDigest, _exclude, _childSelector,_answerOriginKind,_scope,_interestLifetime,_nonce){
+var Interest = function Interest
+ (_name, _faceInstance, _minSuffixComponents, _maxSuffixComponents, _publisherPublicKeyDigest, _exclude,
+ _childSelector, _answerOriginKind, _scope, _interestLifetime, _nonce) {
this.name = _name;
this.faceInstance = _faceInstance;
@@ -1451,7 +1508,18 @@
return false;
return true;
-}
+};
+
+/*
+ * Return a new Interest with the same fields as this Interest.
+ * Note: This does NOT make a deep clone of the name, exclue or other objects.
+ */
+Interest.prototype.clone = function() {
+ return new Interest
+ (this.name, this.faceInstance, this.minSuffixComponents, this.maxSuffixComponents,
+ this.publisherPublicKeyDigest, this.exclude, this.childSelector, this.answerOriginKind,
+ this.scope, this.interestLifetime, this.nonce);
+};
/*
* Handle the interest Exclude element.
@@ -7633,7 +7701,9 @@
// For fetching data
NDN.PITTable = new Array();
+var DebugPITEntryCounter = 0;
var PITEntry = function PITEntry(interest, closure) {
+ this.debugId = ++DebugPITEntryCounter;
this.interest = interest; // Interest
this.closure = closure; // Closure
this.timerID = -1; // Timer ID
@@ -7747,7 +7817,9 @@
* Do the work of reconnectAndExpressInterest once we know we are connected. Set the PITTable and call
* this.transport.send to send the interest.
*/
+var DebugExpressInterestCounter = 0;
NDN.prototype.expressInterestHelper = function(interest, closure) {
+ var expressInterestId = ++DebugExpressInterestCounter; //DEBUG
var binaryInterest = encodeToBinaryInterest(interest);
var thisNDN = this;
//TODO: check local content store first
@@ -7766,6 +7838,8 @@
// the interest because we don't want to match it in the mean time.
// TODO: Make this a thread-safe operation on the global PITTable.
var index = NDN.PITTable.indexOf(pitEntry);
+ if (index >= 0) console.log("expressInterest " + expressInterestId + ": timeout. remove PIT " +
+ pitEntry.debugId); else console.log("can't find PIT " + pitEntry.debugId); //DEBUG
if (index >= 0)
NDN.PITTable.splice(index, 1);
@@ -7779,6 +7853,9 @@
}
};
pitEntry.timerID = setTimeout(timeoutCallback, timeoutMilliseconds);
+ console.log("expressInterest " + expressInterestId + ": (lifetime " + interest.interestLifetime +
+ ") PIT " + pitEntry.debugId + " " + interest.name.to_uri() +
+ (interest.childSelector != null ? " childSelector " + interest.childSelector : "")); //DEBUG
}
this.transport.send(binaryInterest);
@@ -7911,20 +7988,20 @@
co.from_ccnb(decoder);
var pitEntry = NDN.getEntryForExpressedInterest(co.name);
+ if (pitEntry == null) console.log("PIT search failed for " + co.name.to_uri());//DEBUG
if (pitEntry != null) {
- //console.log(pitEntry);
+ // Cancel interest timer
+ clearTimeout(pitEntry.timerID);
+
// Remove PIT entry from NDN.PITTable
var index = NDN.PITTable.indexOf(pitEntry);
+ if (index >= 0) console.log("received. remove PIT " + pitEntry.debugId + ". " + co.name.to_uri());
+ else console.log("can't find PIT " + pitEntry.debugId); //DEBUG
if (index >= 0)
NDN.PITTable.splice(index, 1);
var currentClosure = pitEntry.closure;
-
- // Cancel interest timer
- clearTimeout(pitEntry.timerID);
- //console.log("Clear interest timer");
- //console.log(currentClosure.timerID);
-
+
if (this.verify == false) {
// Pass content up without verifying the signature
currentClosure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED, new UpcallInfo(this, null, 0, co));