We only throttle data packets. Ian has suggested that we can avoid a global data packet queue by the following:
When we want to send a data packet, we already have a delay, lets call it localDelay. This depends on the AIMD throttle for that particular transfer. We don't want to under any circumstances send a packet more frequently than once every minPacketDelay milliseconds. This is specified by the bandwidth limiter. We keep a global variable, lastPacketSendTime. This is the time at which the next packet will be sent. So: The earliest time at which we can send another packet is lastPacketSendTime + Math.max(localDelay, minPacketDelay). This then becomes the new lastPacketSendTime. However, this may be in the past. If we haven't sent any packets for a while, lastPacketSendTime could be a long time ago, and when we do send a packet, we'd end up sending a whole bunch of them in rapid succession without any throttling, until lastPacketSendTime caught up with the present. Now, this is clearly not beneficial for the "hard" general bandwidth limit. The solution is simply to make it: max(lastPacketSendTime + max(localDelay, minPacketDelay), currentTime()) This would allow us to send a packet immediately if we haven't sent one for ages. Oh, and this must happen synchronized. However, it *could* be beneficial for other applications. Soft bandwidth limiting for people on X GB/mo transfer limits, for example. So, we could have two lastPacketSendTime's, and two minPacketDelay's. The first is the hard limit. We must update this every time we send a packet (if it is in the past, since sometimes packet sends will be delayed), and we don't allow it to be in the past when updating it above. The second is the soft limit. This will have a larger minPacketDelay, because it is a lower limit. However, we don't need to be as strict with timekeeping. It is perfectly acceptable to have a burst of packets if we haven't sent any for ages. The two parameters are: - What the limit is - How big the burst can be If we want, for example, never to send more than 500,000 packets in a given 24 hour period, how can we acheive this? If the last packet was sent 24 hours ago, we could send half a million packets immediately. However, we would then be unable to send any more for another 24 hours. Let us suppose that we make lastPacketSendTime never be more than 1 hour behind the present. Suppose we send some packets, then there is a gap in transmission of 1 hour. We can now send a burst of up to 1 hour's worth of packets, i.e. around 20,833 packets. In the hour leading up to the end of the burst, we have just met our quota. In the hour after the start of the burst, we can send packets at the nominal rate. The result of this is two hours worth of packets sent in the hour starting at the start of the burst. However, this is balanced by the emptiness preceding it; over the two hours around the burst, we meet our target exactly. So to get accurate, averaged bandwidth limiting, all we have to do is set the latency limit to half of the period over which we want it to average out. If we have a limit of 5GB per 28 days, which is around 3.8 million packets (assuming lots of overhead), or 1.6 packets per second, we set minPacketDelaySoft to 1.6 seconds and the maximum latency to 14 days. Practical issues? This would have to be saved to disk over such a long period. If we save it every 60 seconds, then on restart we can calculate the maximum number of packets that could have been sent in that period, assume that they were, and that the node was shut down on the instant of writing the next update, and update the lastPacketSendTimeSoft accordingly. That is, assuming that the maximum latency is sufficiently large. -- Matthew J Toseland - toad at amphibian.dyndns.org Freenet Project Official Codemonkey - http://freenetproject.org/ ICTHUS - Nothing is impossible. Our Boss says so. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Digital signature URL: <https://emu.freenetproject.org/pipermail/tech/attachments/20051130/8d481a32/attachment.pgp>
