2005-04-20 jrandom

* In the SDK, we don't actually need to block when we're sending a message
      as BestEffort (and these days, we're always sending BestEffort).
    * Pass out client messages in fewer (larger) steps.
    * Have the InNetMessagePool short circuit dispatch requests.
    * Have the message validator take into account expiration to cut down on
      false positives at high transfer rates.
    * Allow configuration of the probabalistic window size growth rate in the
      streaming lib's slow start and congestion avoidance phases, and default
      them to a more conservative value (2), rather than the previous value
      (1).
    * Reduce the ack delay in the streaming lib to 500ms
    * Honor choke requests in the streaming lib (only affects those getting
      insanely high transfer rates)
    * Let the user specify an interface besides 127.0.0.1 or 0.0.0.0 on the
      I2PTunnel client page (thanks maestro^!)
(plus minor udp tweaks)
This commit is contained in:
jrandom
2005-04-20 19:15:25 +00:00
committed by zzz
parent 1861379d43
commit a2c7c5a516
17 changed files with 222 additions and 63 deletions

View File

@ -135,6 +135,8 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
} catch (IOException ioe) {
throw new I2PSessionException("Error reading the destination key stream", ioe);
}
if (options == null)
options = System.getProperties();
loadConfig(options);
_sessionId = null;
_leaseSet = null;

View File

@ -50,6 +50,14 @@ class I2PSessionImpl2 extends I2PSessionImpl {
super(ctx, destKeyStream, options);
_log = ctx.logManager().getLog(I2PSessionImpl2.class);
_sendingStates = new HashSet(32);
ctx.statManager().createRateStat("i2cp.sendBestEffortTotalTime", "how long to do the full sendBestEffort call?", "i2cp", new long[] { 10*60*1000 } );
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage0", "first part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage1", "second part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage2", "third part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage3", "fourth part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage4", "fifth part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
}
protected long getTimeout() {
@ -158,7 +166,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
long nonce = _context.random().nextInt(Integer.MAX_VALUE);
if (_log.shouldLog(Log.DEBUG)) _log.debug("before sync state");
MessageState state = new MessageState(nonce, getPrefix());
MessageState state = new MessageState(_context, nonce, getPrefix());
state.setKey(key);
state.setTags(sentTags);
state.setNewKey(newKey);
@ -196,7 +204,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
// saying that the router received it - in theory, that should come back
// immediately, but in practice can take up to a second (though usually
// much quicker). setting this to false will short-circuit that delay
boolean actuallyWait = true;
boolean actuallyWait = false; // true;
long beforeWaitFor = _context.clock().now();
if (actuallyWait)
@ -226,6 +234,13 @@ class I2PSessionImpl2 extends I2PSessionImpl {
+ (afterRemovingSync-beforeWaitFor) + "ms waiting for reply");
}
_context.statManager().addRateData("i2cp.sendBestEffortTotalTime", afterRemovingSync - begin, 0);
//_context.statManager().addRateData("i2cp.sendBestEffortStage0", beforeSendingSync- begin, 0);
//_context.statManager().addRateData("i2cp.sendBestEffortStage1", afterSendingSync- beforeSendingSync, 0);
//_context.statManager().addRateData("i2cp.sendBestEffortStage2", beforeWaitFor- afterSendingSync, 0);
//_context.statManager().addRateData("i2cp.sendBestEffortStage3", afterWaitFor- beforeWaitFor, 0);
//_context.statManager().addRateData("i2cp.sendBestEffortStage4", afterRemovingSync- afterWaitFor, 0);
if (found) {
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix() + "Message sent after " + state.getElapsed() + "ms with "
@ -260,7 +275,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
newKey = _context.keyGenerator().generateSessionKey();
long nonce = _context.random().nextInt(Integer.MAX_VALUE);
MessageState state = new MessageState(nonce, getPrefix());
MessageState state = new MessageState(_context, nonce, getPrefix());
state.setKey(key);
state.setTags(sentTags);
state.setNewKey(newKey);
@ -418,6 +433,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
_log.info(getPrefix() + "No matching state for messageId " + msgId + " / " + nonce
+ " w/ status = " + status);
}
_context.statManager().addRateData("i2cp.receiveStatusTime", _context.clock().now() - beforeSync, 0);
}
/**

View File

@ -4,6 +4,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.data.Destination;
import net.i2p.data.SessionKey;
import net.i2p.data.i2cp.MessageId;
@ -16,6 +17,7 @@ import net.i2p.util.Log;
*
*/
class MessageState {
private I2PAppContext _context;
private final static Log _log = new Log(MessageState.class);
private long _nonce;
private String _prefix;
@ -31,8 +33,9 @@ class MessageState {
private static long __stateId = 0;
private long _stateId;
public MessageState(long nonce, String prefix) {
public MessageState(I2PAppContext ctx, long nonce, String prefix) {
_stateId = ++__stateId;
_context = ctx;
_nonce = nonce;
_prefix = prefix + "[" + _stateId + "]: ";
_id = null;
@ -42,7 +45,8 @@ class MessageState {
_newKey = null;
_tags = null;
_to = null;
_created = Clock.getInstance().now();
_created = ctx.clock().now();
//ctx.statManager().createRateStat("i2cp.checkStatusTime", "how long it takes to go through the states", "i2cp", new long[] { 60*1000 });
}
public void receive(int status) {
@ -99,32 +103,41 @@ class MessageState {
}
public long getElapsed() {
return Clock.getInstance().now() - _created;
return _context.clock().now() - _created;
}
public void waitFor(int status, long expiration) {
while (true) {
long checkTime = -1;
boolean found = false;
while (!found) {
if (_cancelled) return;
long timeToWait = expiration - Clock.getInstance().now();
long timeToWait = expiration - _context.clock().now();
if (timeToWait <= 0) {
if (_log.shouldLog(Log.WARN))
_log.warn(_prefix + "Expired waiting for the status [" + status + "]");
return;
}
found = false;
synchronized (_receivedStatus) {
long beforeCheck = _context.clock().now();
if (locked_isSuccess(status) || locked_isFailure(status)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(_prefix + "Received a confirm (one way or the other)");
return;
found = true;
}
if (timeToWait > 5000) {
timeToWait = 5000;
}
try {
_receivedStatus.wait(timeToWait);
} catch (InterruptedException ie) { // nop
checkTime = _context.clock().now() - beforeCheck;
if (!found) {
if (timeToWait > 5000) {
timeToWait = 5000;
}
try {
_receivedStatus.wait(timeToWait);
} catch (InterruptedException ie) { // nop
}
}
}
//if (found)
// _context.statManager().addRateData("i2cp.checkStatusTime", checkTime, 0);
}
}

View File

@ -61,6 +61,18 @@ public class DecayingBloomFilter {
SimpleTimer.getInstance().addEvent(_decayEvent, _durationMs);
}
public long getCurrentDuplicateCount() { return _currentDuplicates; }
public int getInsertedCount() {
synchronized (this) {
return _current.size() + _previous.size();
}
}
public double getFalsePositiveRate() {
synchronized (this) {
return _current.falsePositives();
}
}
/**
* return true if the entry added is a duplicate
*