I am not sure I see what this has to do with NGrouting exactly - am
I missing something?
Ian.
On Fri, Jun 20, 2003 at 07:30:30PM -0400, Ed Tomlinson wrote:
> Hi,
>
> Here are the patches that make this work.
>
> Comments on devl still apply. With the defference that this does not use
> the number of references to decide how much to favor a node getting a new
> reference. Now it uses the sqrt(message success rate) to do this. This prevents
> an attack where a 'baddy' sends lots of refs...
>
> The stats it reports in the routing applet are much improved too.
>
> Comments?
>
> Ed
>
> in node/rt
>
> -----------------
> --- CPAlgoRoutingTable.java 2003-06-19 09:31:20.000000000 -0400
> +++ CPAlgoRoutingTable.java.new 2003-06-20 18:27:48.000000000 -0400
> @@ -66,12 +66,23 @@
> this.minDowntimeARKLookup = minDowntimeARKLookup;
> this.minCP = minCP;
> this.maxLookupThreads = maxLookupThreads;
> + this.cachedAttempts = 0;
> + this.cachedSuccesses = 0;
> + this.messageAttempts = 0;
> + this.messageSuccesses = 0;
> + this.globalEtime = 0l;
> + aFailed = 0;
> + aTimedOut = 0;
> + tFailed = 0;
> }
>
> int consecutiveFailuresLookupARK;
> int minDowntimeARKLookup;
> float minCP;
> + long globalEtime;
> int maxLookupThreads;
> + int cachedAttempts, cachedSuccesses, messageAttempts, messageSuccesses;
> + int aFailed, aTimedOut, tFailed;
>
> public RTDiagSnapshot getSnapshot() {
> long nowMs = System.currentTimeMillis();
> @@ -80,6 +91,7 @@
> totalRefs = 0;
> contactedRefs = 0;
> requestingRefs = 0;
> + totalKeys = 0;
>
> // ^^^ the fact that you have to do this suggests these
> // should be local variables not instance variables -tc
> @@ -111,6 +123,7 @@
> }
>
> ReferenceSet refSet = ReferenceSet.getProperty(memory, "keys");
> + totalKeys += refSet.size();
> Enumeration refs = refSet.references();
> while (refs.hasMoreElements()) {
> if(shouldLog)
> @@ -153,10 +166,19 @@
> Object[] props = new Object[TABLE_PROPERTIES.length];
> props[0] = new Integer(totalRefs);
> props[1] = new Integer(contactedRefs);
> - props[2] = new Integer(requestingRefs);
> - props[3] = new Integer(totalAttempts);
> - props[4] = new Integer(totalSuccesses);
> - props[5] = getClass().getName();
> + props[2] = new Integer(totalKeys);
> + props[3] = new Integer(requestingRefs);
> + props[4] = new Integer(totalAttempts);
> + props[5] = new Integer(totalSuccesses);
> + props[6] = new Integer(cachedAttempts);
> + props[7] = new Integer(cachedSuccesses);
> + props[8] = new Integer(messageAttempts);
> + props[9] = new Integer(messageSuccesses);
> + props[10] = new Long(globalEtime);
> + props[11] = new Integer(aFailed);
> + props[12] = new Integer(aTimedOut);
> + props[13] = new Integer(tFailed);
> + props[14] = getClass().getName();
>
> Key[] keyList = (Key[])keys.toArray(new Key[keys.size()]);
> if(shouldLog)
> @@ -195,21 +217,11 @@
> }
> }
>
> -
> - private final synchronized void incTrials(RoutingMemory mem) {
> - CPAlgoData cpd = getProperty(mem, RMKEY, node);
> - cpd.trials++;
> - // We don't call mem.setProperty() because trials isn't
> - // persisted.
> - }
> -
> - private final synchronized void fail(RoutingMemory mem) {
> - fail(mem, false);
> - }
> -
> - private final synchronized void fail(RoutingMemory mem, boolean weak) {
> + private final synchronized void fail(RoutingMemory mem, float done, boolean
> cached) {
> CPAlgoData cpd = getProperty(mem, RMKEY, node);
> - if (cpd.decreaseContactProbability(weak)) {
> + if (done == 1.0f)
> + cpd.increaseContactProbability(done);
> + else if (cpd.decreaseContactProbability(done)) {
> remove(mem, null);
> return;
> }
> @@ -221,52 +233,30 @@
> remove((RoutingMemory)(routingStore.getNode(i)), i);
> }
>
> - private final synchronized void succeed(RoutingMemory mem, boolean cached,
> - boolean attenuated, boolean weak) {
> - CPAlgoData cpd = getProperty(mem, RMKEY, node);
> - cpd.successes++;
> - if (!cached) {
> - // Uncached connections don't count.
> - cpd.increaseContactProbability(weak);
> - }
> - mem.setProperty(RMKEY, cpd);
> - }
> -
> - /**
> - * Succeed and/or fail on weak or strong in a single step
> - * @param strongSuccess whether we strongly (connection level) succeded
> - * @param weakSuccess whether we weakly (query level) succeeded
> - * @param ignoreStrong whether to leave the strong component unchanged
> - * - generally set when we are dealing with a cached connection
> + /*
> + * Nodes set references to themselves when they want more
> + * traffic - lets take that into account. This should help
> + * conserve nodes with lots of keys, which should lead to
> + * better route selections.
> */
> - protected final synchronized void succeedFail(RoutingMemory mem,
> - boolean strongSuccess,
> - boolean weakSuccess,
> - boolean ignoreStrong) {
> - CPAlgoData cpd = getProperty(mem, RMKEY, node);
> - if(!ignoreStrong) {
> - if(!strongSuccess) {
> - if(cpd.decreaseContactProbability(false)) {
> - remove(mem, null);
> - return;
> - }
> - } else {
> - cpd.increaseContactProbability(false);
> + public synchronized void reference(Key k, NodeReference nr) {
> + super.reference(k, nr);
> + RoutingMemory mem = routingStore.getNode(nr.getIdentity());
> + if (mem != null) {
> + ReferenceSet refSet = ReferenceSet.getProperty(mem, "keys");
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + if (refSet.size() > 1) {
> + cpd.perturbCP(refSet.size());
> + mem.setProperty(RMKEY, cpd);
> + Core.logger.log(this, "key reference perturbed CP",
> + Core.logger.DEBUG);
> }
> - }
> - if(weakSuccess) {
> - cpd.increaseContactProbability(true);
> } else {
> - if(cpd.decreaseContactProbability(true)) {
> - remove(mem, null);
> - return;
> - }
> + Core.logger.log(this, "key reference found null mem",
> + Core.logger.DEBUG);
> }
> - if(weakSuccess || strongSuccess)
> - cpd.successes++;
> - mem.setProperty(RMKEY, cpd);
> }
> -
> +
> protected boolean isRoutable(RoutingMemory mem,
> boolean desperate) {
> return isRoutable(mem, desperate, "");
> @@ -352,48 +342,133 @@
> Logger.DEBUG);
> }
> }
> -
> +
> + // 33% done.
> protected synchronized void routeConnected(RoutingMemory mem) {
> - incTrials(mem);
> - totalAttempts++;
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + cpd.trials++;
> + totalAttempts++;
> + cpd.state = 1;
> + }
> }
>
> + // 66% done (routed at ip, auth ok)
> protected synchronized void routeAccepted(RoutingMemory mem) {
> - // hmm.. what?
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + if (cpd.state == 1) {
> + cpd.successes++;
> + totalSuccesses++;
> + cpd.state = 0;
> + }
> + }
> }
>
> + // 100% done here
> protected synchronized void routeSucceeded(RoutingMemory mem, boolean cached) {
> - // Don't reward cached connections.
> - succeedFail(mem, true, true, cached);
> - totalSuccesses++;
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + if (!cached && cpd.state == 1) {
> + cpd.successes++;
> + totalSuccesses++;
> + cpd.state = 0;
> + }
> + cpd.cTrials++;
> + cpd.cSuccesses++;
> + cachedAttempts++;
> + cachedSuccesses++;
> + }
> + fail(mem,1.0f,cached);
> }
>
> + // 0% done (did not get routeConnected)
> protected synchronized void connectFailed(RoutingMemory mem) {
> - incTrials(mem);
> - totalAttempts++;
> - fail(mem);
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + cpd.trials++;
> + totalAttempts++;
> + cpd.state = 0;
> + }
> + aFailed++;
> + fail(mem,0.0f,false);
> }
>
> + // 0% done if this happens (have routeConnected but routeAccepted cannot occur)
> protected synchronized void authFailed(RoutingMemory mem) {
> - fail(mem);
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + cpd.state = 0;
> + }
> + fail(mem,0.0f,false);
> // don't deref it completely in case this is corruption or something
> - // don't ignore it because we want to clear out nodes that change identity
> reasonably quickly
> + // don't ignrore it because we want to clear out nodes that change identity
> reasonably quickly
> }
>
> + // 5% done - seems only to be called during setup of the route. We give it 5%
> since
> + // we did find something, but it was too busy to respond
> protected synchronized void timedOut(RoutingMemory mem) {
> - fail(mem);
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + if (cpd.state == 0) {
> + cpd.trials++;
> + totalAttempts++;
> + }
> + cpd.state = 0;
> + }
> + aTimedOut++;
> + fail(mem,minCP,false);
> }
>
> + // 5% done - suspect this happens after routeSucceeded, no counts are affected.
> This
> + // does not happen enought to really matter...
> protected synchronized void transferFailed(RoutingMemory mem) {
> - fail(mem);
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + cpd.state = 0;
> + }
> + tFailed++;
> + fail(mem,minCP,false);
> }
>
> - // this is not a tyop!
> + // this is not a tyop! No Fail call since we are removing the node...
> protected synchronized void verityFailed(RoutingMemory mem) {
> // dereference node
> remove(mem, null);
> }
>
> + // NGish routing
> + protected synchronized void searchFailed(RoutingMemory mem, Key k, long time,
> int htl) {
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + cpd.mTrials++;
> + messageAttempts++;
> + }
> + }
> +
> + // NGish routing
> + protected synchronized void messageFailed(RoutingMemory mem, Key k, long time,
> int htl, long etime) {
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + cpd.mTrials++;
> + messageAttempts++;
> + }
> + }
> +
> + // NGish routing
> + protected synchronized void messageSucceeded(RoutingMemory mem, Key k, long
> time, int htl, long etime) {
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + cpd.mTrials++;
> + cpd.mSuccesses++;
> + messageAttempts++;
> + messageSuccesses++;
> + // use 0.1, later a kalman filter may make sense.
> + cpd.etime = cpd.etime + (etime - cpd.etime)/10l;
> + globalEtime = globalEtime + (etime - globalEtime)/10l;
> + }
> + }
> +
> private final synchronized boolean deleteReferences(ReferenceSet refSet,
> long number) {
> if(Core.logger.shouldLog(Core.logger.DEBUG))
> @@ -424,6 +499,8 @@
> // Reduce the chances of routing to nodes that always
> // replies with QueryRejected.
> protected synchronized void queryRejected(RoutingMemory mem, boolean cached,
> long attenuation) {
> + float rp = 0.6f; // route success as measured
> + float cp = 0.75f; // connect success as measured
>
> // I would have preferred to make queryRejected() in addition
> // to routeSucceeded() to keep transport and application
> @@ -432,9 +509,29 @@
> // Counter-intutitive. The routing has succeeded at the
> // transport layer, but we got a QueryRejected
> // back at the application layer.
> - //
> - succeedFail(mem, true, false, cached);
> - totalSuccesses++;
> +
> + synchronized(mem) {
> + CPAlgoData cpd = getProperty(mem, RMKEY, node);
> + if (!cached && cpd.state == 1) {
> + cpd.successes++;
> + totalSuccesses++;
> + cpd.state = 0;
> + }
> + cpd.cTrials++;
> + cachedAttempts++;
> +
> + // we bottom out at 0.01 since this is not a routing failure
> + if (cpd.trials > 0)
> + rp = java.lang.Math.max(((float) cpd.successes) / ((float)
> cpd.trials), 0.01f);
> +
> + if (cpd.cTrials > 0)
> + cp = java.lang.Math.max(((float) cpd.cSuccesses) / ((float)
> cpd.cTrials), 0.01f);
> + }
> +
> + if (cached)
> + fail(mem, cp, cached); // it was cached, next try probably will be too
> + else
> + fail(mem, rp*cp, cached); // we started from scratch probably will next
> time
>
> // Disable routing attenuation. 20020421 --gj
> //
> @@ -466,15 +563,18 @@
> ////////////////////////////////////////////////////////////
> // Helper functions used to implement diagnostic snapshots.
> private final static String[] REF_PROPERTIES
> - = {"Address", "Contact Probability", "Consecutive Failures",
> - "Connection Attempts", "Successful Connections",
> + = {"Address", "Contact Weight", "Successfull Routes",
> + "Successfull Connections", "Successfull Messages",
> "Last Attempt", "NodeReference", "Node Version", "Key Count",
> "ARK version", "Fetching ARK", "ARK URL"};
>
> private final static String[] TABLE_PROPERTIES
> - = {"Number of node references", "Contacted node references",
> - "Node references requesting ARKs", "Total Trials",
> - "Total Successes", "Implementation" };
> + = {"Number of node references", "Contacted node references", "Total
> Reference Keys",
> + "Node references requesting ARKs",
> + "Route Trials", "Route Successes",
> + "Cached Trials", "Cached Successes",
> + "Message Trials", "Message Successes", "Successfull Messages etime",
> + "Route Failures", "TimedOut", "TransferFailed", "Implementation" };
>
> // ^^^ i don't understand why you are doing this here
> // instead of just passing the NodeReference back -tc
> @@ -512,6 +612,7 @@
> // Diagnostic stats set by makeRefInfo
> private int totalRefs = 0;
> private int requestingRefs = 0;
> + private int totalKeys = 0;
> private int contactedRefs = 0;
>
> private final Long LONG_MINUS_ONE = new Long(-1);
> @@ -553,10 +654,9 @@
> values[0] = ref.firstPhysicalToString();
> // Don't phreak out cluebies with 0.0 cp during backoff.
> values[1] = new Float(cpd.effectiveCP(nowMs));
> - values[2] = new Long(cpd.consecutiveFailures);
> - ///values[2] = new Integer(cpd.failureIntervals);
> - values[3] = new Long(cpd.trials);
> - values[4] = new Long(cpd.successes);
> + values[2] = new long[] {cpd.successes, cpd.trials};
> + values[3] = new long[] {cpd.cSuccesses, cpd.cTrials};
> + values[4] = new long[] {cpd.mSuccesses, cpd.mTrials, cpd.etime};
> ///values[5] = backedOffSecs(cpd, nowMs);
> values[5] = lastAttemptSecs(cpd, nowMs, cpd.lastRetryMs);
> values[6] = ref; // refs are immutable
> @@ -565,7 +665,10 @@
> ReferenceSet refSet = ReferenceSet.getProperty(mem, "keys");
> values[8] = new Long(refSet.size());
> values[9] = new Long(ref.revision());
> - values[10] = new Boolean(cpd.fetchingARK());
> + if (cpd.fetchingARK())
> + values[10] = new Long(-cpd.consecutiveFailures);
> + else
> + values[10] = new Long(cpd.consecutiveFailures);
> FreenetURI uri = ref.getARKURI(ref.revision());
> if(uri != null)
> values[11] = uri.toString(false);
> @@ -654,12 +757,22 @@
> **/
> class CPAlgoData implements DataObject {
>
> - // persisted.
> - float contactProbability = 1.0f;
> + // persisted. Initial is rp=0.60 x cp=0.75 or about 0.45
> + private float contactProbability = 0.45f;
> +
> + // better, but not foolproof timeout handling (0=initial, 1=routed)
> + int state = 0;
>
> // Diagnostic info
> long successes = 0;
> long trials = 0;
> + long cSuccesses = 0;
> + long cTrials = 0;
> + long mSuccesses = 0;
> + long mTrials = 0;
> +
> + // how fast does data flow from this node
> + long etime = 0l;
>
> // Number of consecutive failures
> long consecutiveFailures = 0;
> @@ -760,55 +873,74 @@
>
> final float contactProbability() {
> if(contactProbability < minCP) {
> - contactProbability = minCP;
> - return minCP;
> + contactProbability = minCP;
> + return minCP;
> }
> return contactProbability;
> }
> -
> +
> + final void perturbCP(int keys) {
> + float t = 0.0f;
> + if (mTrials > 0)
> + t = (float)mSuccesses/(float)mTrials;
> + // use the global message success rate (0.05) if we have not seen many
> messages
> + if (mTrials < 20 && t < 0.05f)
> + t = 0.05f;
> + nextCP(1.0f, (float)java.lang.Math.sqrt(t));
> +
> + }
> +
> + final void nextCP(float value) {
> + nextCP(value, 0.1f);
> + }
> +
> + // I tried a Kakman predictor here, but using k = 0.1 works as well...
> + final void nextCP(float value, float k) {
> + // r is measured noise variance
> + // q is plant noise variance
> + // in the limit k = sqrt(q/r) and p = sqrt(q*r)
> + // k = p/(p+r);
> + contactProbability = contactProbability + k*(value - contactProbability);
> + // p = (1-k)*p+q;
> + }
> +
> // returns true if the node should be dereferenced.
> - final boolean decreaseContactProbability(boolean weak) {
> - contactProbability =
> - (float)(weak ? ((96.0 * contactProbability) / 100.0) :
> - (((4.0 * contactProbability) /* + 0.0 */) / 5.0));
> - // Decrease by 4% for weak, 20% for strong
> - if(contactProbability < minCP) contactProbability = minCP;
> - consecutiveFailures++;
> - // When consecutiveFailures reaches some value, start an ARK lookup
> - if(consecutiveFailures >= consecutiveFailuresLookupARK &&
> - lastSuccessfulContact + minDowntimeARKLookup <
> - System.currentTimeMillis()) {
> - synchronized(lookupLock) {
> - if(node == null) throw new IllegalStateException
> + final boolean decreaseContactProbability(float done) {
> + nextCP(done);
> + // When consecutiveFailures reaches some value, start an ARK lookup and
> + // its only a failure, in ARK terms, if the passed probability is zero.
> + if(done > 0f)
> + consecutiveFailures = 0;
> + else {
> + consecutiveFailures++;
> + if (consecutiveFailures >= consecutiveFailuresLookupARK &&
> + lastSuccessfulContact + minDowntimeARKLookup <
> + System.currentTimeMillis()) {
> + synchronized(lookupLock) {
> + if(node == null) throw new IllegalStateException
> ("creating LookupARK with null node");
> - if(lookup == null && getARKURI() != null) {
> - synchronized(lookupThreadsLock) {
> - if(lookupThreads < maxLookupThreads)
> - lookup = new LookupARK(getARKURI());
> - }
> + if(lookup == null && getARKURI() != null) {
> + synchronized(lookupThreadsLock) {
> + if(lookupThreads < maxLookupThreads)
> + lookup = new LookupARK(getARKURI());
> + }
> // FIXME: Kill the LookupARK whose ref is least recently used
> + }
> }
> - }
> + }
> }
> lastRetryMs = System.currentTimeMillis();
> return false;
> }
>
> - final void increaseContactProbability(boolean weak) {
> + final void increaseContactProbability(float done) {
> if(justFetchedARK) {
> node.diagnostics.occurrenceCounting("successLookupARK",1);
> justFetchedARK = false;
> }
> - if(contactProbability < minCP) contactProbability = minCP;
> + nextCP(done);
> + lastSuccessfulContact = lastRetryMs = System.currentTimeMillis();
> consecutiveFailures = 0;
> - float f = (float)
> - (weak ? (((19 * contactProbability) + 1.0) / 20.0) :
> - (((3.0 * contactProbability) + 1.0) / 4.0));
> - // Move closer to 1.0 by 5% for weak
> - // 25% for strong
> - if(f>1) f = 1;
> - contactProbability = f;
> - lastRetryMs = lastSuccessfulContact = System.currentTimeMillis();
> synchronized(lookupLock) {
> if(lookup != null) {
> lookup.kill();
> @@ -816,7 +948,7 @@
> }
> }
> }
> -
> +
> final boolean fetchingARK() {
> return lookup != null;
> }
>
> ------------
> --- Routing.java 2003-04-19 11:32:54.000000000 -0400
> +++ Routing.java.new 2003-06-20 18:07:48.000000000 -0400
> @@ -2,6 +2,7 @@
>
> import freenet.Identity;
> import freenet.node.NodeReference;
> +import freenet.Key;
>
> /**
> * Supplies a sequence of NodeReferences in order of routing
> @@ -101,6 +102,12 @@
> * request is answered with a QueryRejected.
> */
> void queryRejected(boolean cached, long attenuation);
> +
> + void searchFailed(Key key, long time, int htl);
> +
> + void messageFailed(Key key, long time, int htl, long etime);
> +
> + void messageSucceeded(Key key, long time, int htl, long etime);
> }
>
>
> --------------------
> --- TreeRouting.java 2003-06-19 09:31:20.000000000 -0400
> +++ TreeRouting.java.new 2003-06-20 18:36:26.000000000 -0400
> @@ -6,6 +6,7 @@
> import freenet.support.BinaryTree.Node;
> import freenet.support.MetricWalk;
> import freenet.Core;
> +import freenet.Key;
> import java.util.Hashtable;
>
> /**
> @@ -221,6 +222,19 @@
> public final void queryRejected(boolean cached, long attenuation) {
> rt.queryRejected(mem, cached, attenuation);
> }
> +
> + public final void searchFailed(Key k, long time, int htl) {
> + rt.searchFailed(mem, k, time, htl);
> + }
> +
> + public final void messageSucceeded(Key k, long time, int htl, long etime) {
> + rt.messageSucceeded(mem, k, time, htl, etime);
> + }
> +
> + public final void messageFailed(Key k, long time, int htl, long etime) {
> + rt.messageFailed(mem, k, time, htl, etime);
> + }
> +
> }
>
>
> ------------
> --- TreeRoutingTable.java 2003-05-16 21:28:02.000000000 -0400
> +++ TreeRoutingTable.java.new 2003-06-20 18:08:35.000000000 -0400
> @@ -259,6 +259,14 @@
> protected abstract void verityFailed(RoutingMemory mem);
>
> protected abstract void queryRejected(RoutingMemory mem, boolean cached, long
> attenuation);
> +
> + // then one of these per message (for NG Routing):
> +
> + protected abstract void searchFailed(RoutingMemory mem, Key k, long time, int
> htl);
> +
> + protected abstract void messageSucceeded(RoutingMemory mem, Key k, long time,
> int htl, long etime);
> +
> + protected abstract void messageFailed(RoutingMemory mem, Key k, long time, int
> htl, long etime);
> }
>
>
>
> --------------
>
> in client/http
>
> -------------
> --- NodeStatusServlet.java 2003-06-05 21:08:37.000000000 -0400
> +++ NodeStatusServlet.java.new 2003-06-20 18:12:20.000000000 -0400
> @@ -1669,19 +1669,26 @@
> }
>
> if (rtType.equals("freenet.node.rt.CPAlgoRoutingTable")) {
> - long attempts = ((Long)refValues[3]).longValue();
> - long successful = ((Long)refValues[4]).longValue();
> - if (attempts > 0 && successful > 0) {
> - // percent successful
> - refValues[4] = refValues[4].toString() + " ("
> - + (long) (100 * successful / (double)attempts) + "%)";
> - }
> + long attempts = ((long[])refValues[2])[1];
> + long successful = ((long[])refValues[2])[0];
> + refValues[2] = successful+ " / "
> + + attempts ;
>
> + attempts = ((long[])refValues[3])[1];
> + successful = ((long[])refValues[3])[0];
> + refValues[3] = successful+ " / "
> + + attempts ;
> +
> + attempts = ((long[])refValues[4])[1];
> + successful = ((long[])refValues[4])[0];
> + long etime = ((long[])refValues[4])[2];
> + refValues[4] = successful+ " / "
> + + attempts +" : " + etime;
> +
> + long failures = (long)((Long)refValues[10]).longValue();
> boolean failing = true;
> - if (refValues[2].equals(ZERO)) {
> - refValues[2] = "none";
> + if (failures == 0)
> failing = false;
> - }
>
> long ver = ((Long)refValues[9]).longValue();
> NodeReference ref = (NodeReference)refValues[6];
> @@ -1689,23 +1696,23 @@
> String s = " <font color=\"";
> String v = "";
>
> - if (refValues[10].equals(TRUE))
> + if (failures < 0)
> v = "blue"; // Fetching ARK
> else if (failing)
> v = "red"; // Failing
> else if (!refValues[4].equals(ZERO))
> v = "green"; // Working fine
>
> - if(refValues[10].equals(TRUE)) {
> + if(failures < 0) {
> if(ref.getARKURI(ver+1) == null) {
> refValues[10] = "broken"; // it will fail soon enough
> } else {
> refValues[10] = "<a href=\"/"+
> ref.getARKURI(ver+1).toString(false)+
> - "\">yes</a>";
> + "\">yes</a> ("+(-failures)+")";
> }
> } else {
> - refValues[10] = "no";
> + refValues[10] = "no ("+refValues[10].toString()+")";
> }
>
> // Black means not connected yet
> --------------
>
> and in node/states/request
>
> -----------------
> --- Pending.java 2003-06-19 09:31:20.000000000 -0400
> +++ Pending.java.new 2003-06-20 18:51:31.000000000 -0400
> @@ -731,6 +731,8 @@
> long expectedTime = (replyTime - routedTime) +
> (((endTransferTime - replyTime) * stdFileSize) /
> receivingData.length());
> +
> + routes.messageSucceeded(searchKey, replyTime-routedTime, hopsToLive,
> expectedTime);
> if(logDEBUG)
> n.logger.log(this, "NGROUTING: Key "+searchKey+": search took "+
> (replyTime-routedTime)+" in "+hopsToLive+", transfer took "+
> @@ -763,6 +765,7 @@
> public void logFailedTransfer(Node n, long endTime) {
> if(loggedResult) return;
> loggedResult = true;
> + routes.messageFailed(searchKey, replyTime-routedTime, hopsToLive, 0l);
> if(logDEBUG)
> n.logger.log(this, "NGROUTING: Key "+searchKey+": search took "+
> (replyTime-routedTime)+" in "+hopsToLive+
> @@ -774,6 +777,7 @@
> public void logFailedSearch(Node n, long endTime) {
> if(loggedResult) return;
> loggedResult = true;
> + routes.searchFailed(searchKey, replyTime-routedTime, hopsToLive);
> if(logDEBUG)
> n.logger.log(this, "NGROUTING: Key "+searchKey+": search failed in "+
> (endTime-routedTime)+" for "+hopsToLive+"; sent to "+
> -------------
> _______________________________________________
> devl mailing list
> [EMAIL PROTECTED]
> http://hawk.freenetproject.org:8080/cgi-bin/mailman/listinfo/devl
--
Ian Clarke [EMAIL PROTECTED]
Coordinator, The Freenet Project http://freenetproject.org/
Founder, Locutus http://locut.us/
Personal Homepage http://locut.us/ian/
_______________________________________________
devl mailing list
[EMAIL PROTECTED]
http://hawk.freenetproject.org:8080/cgi-bin/mailman/listinfo/devl