File: rpc2-rtt-adaptive.lua

package info (click to toggle)
rpc2 2.7%2Bdebian-5
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 2,852 kB
  • ctags: 2,661
  • sloc: ansic: 19,928; sh: 9,110; lex: 437; yacc: 416; makefile: 126; asm: 35
file content (115 lines) | stat: -rw-r--r-- 3,030 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
--
-- RPC2's bandwidth and latency estimator
--

print "loading adaptive estimator"

-- These globals are set by RPC2
-- RPC2_RETRIES = 5
-- RPC2_TIMEOUT = time(15.0)

local RTT_SCALE = 8
local RTTVAR_SCALE = 4
local BW_SCALE = 16

local function estimate(host, bytes_sent, bytes_recv)
    local BW_send, BW_recv, rtt_lat, rtt_send, rtt_recv, rto

    BW_send, BW_recv = rtt_getbandwidth(host)
    rtt_lat = host.RTT / RTT_SCALE
    rtt_send = bytes_sent / BW_send
    rtt_recv = bytes_recv / BW_recv
    rto = rtt_lat + rtt_send + rtt_recv

    return rto, rtt_lat, rtt_send, rtt_recv
end

local function update_bw(bw_lo, bw_hi, rtt, bytes)
    local bw_cur, bw_est
    local BW_SCALE = BW_SCALE

    bw_cur = rtt / bytes
    bw_est = 1 / bw_lo
    bw_est = bw_est + (bw_cur - bw_est) / BW_SCALE
    bw_lo = 1 / bw_est

    bw_cur = bytes / rtt
    bw_hi = bw_hi + (bw_cur - bw_hi) / BW_SCALE

    return bw_lo, bw_hi
end

function rtt_init(host)
    host.RTT = time(0)
    host.RTTvar = time(0)
    host.BW_send_lo = 100000
    host.BW_send_hi = 100000
    host.BW_recv_lo = 100000
    host.BW_recv_hi = 100000
end

function rtt_update(host, elapsed, bytes_sent, bytes_recv)
    local rto, rtt_lat, rtt_send, rtt_recv, err

    -- Get current estimates
    rto, rtt_lat, rtt_send, rtt_recv = estimate(host, bytes_sent, bytes_recv)

    --[[
    print("uRTT", host.name, elapsed, bytes_sent, bytes_recv, rto, rtt_lat,
	  host.BW_send_lo, host.BW_send_hi, host.BW_recv_lo, host.BW_recv_hi)
    --]]

    -- Calculate error and desired correction
    if elapsed >= rto then
	err = (elapsed - rto) / 3
	rtt_send = rtt_send + err
	rtt_recv = rtt_recv + err
    else
	err = elapsed / 3
	rtt_send = err
	rtt_recv = err
	err = err - rtt_lat
    end

    -- Update estimates
    host.RTT = host.RTT + err
    err = err - host.RTTvar / RTTVAR_SCALE
    host.RTTvar = host.RTTvar + err

    host.BW_send_lo, host.BW_send_hi =
	update_bw(host.BW_send_lo, host.BW_send_hi, rtt_send, bytes_sent)

    host.BW_recv_lo, host.BW_recv_hi =
	update_bw(host.BW_recv_lo, host.BW_recv_hi, rtt_recv, bytes_recv)
end

function rtt_getbandwidth(host)
    local avg_send, avg_recv
    avg_send = (host.BW_send_lo + host.BW_send_hi) / 2
    avg_recv = (host.BW_recv_lo + host.BW_recv_hi) / 2
    return avg_send, avg_recv
end

function rtt_getrto(host, bytes_sent, bytes_recv)
    local rtt = (estimate(host, bytes_sent, bytes_recv))
    -- print("est", host.name, rtt, bytes_sent, bytes_recv)
    return rtt + host.RTTvar / 2
end

function rtt_retryinterval(host, attempt, bytes_sent, bytes_recv)
    local rto, timeout, retry
    if attempt > RPC2_RETRIES then return nil end

    rto = (estimate(host, bytes_sent, bytes_recv))
    if attempt == 0 then return rto end

    timeout, retry = RPC2_TIMEOUT / 2, 0
    for i = RPC2_RETRIES, 1, -1 do
	if rto > timeout then retry = i break end
	timeout = timeout / 2
    end
    if retry + attempt > RPC2_RETRIES then return nil end
    for i = 1, attempt do timeout = timeout * 2 end
    return timeout
end