summaryrefslogtreecommitdiff
path: root/src/channel.moon
diff options
context:
space:
mode:
Diffstat (limited to 'src/channel.moon')
-rw-r--r--src/channel.moon25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/channel.moon b/src/channel.moon
index 968ae09..6f87d46 100644
--- a/src/channel.moon
+++ b/src/channel.moon
@@ -34,26 +34,31 @@ class FaultyChannel extends Channel
@avg_latency = 0 -- in ms
@latency_std = 0
-- Latency can never be below 0, but can go up as much as it likes
- @avg_loss = 0 -- between 0 (never) and 1 (always)
- @loss_std = 0.1
- -- Loss is always a percentage between 0 and 1
+ @loss = 0.1 -- between 0 (never) and 1 (always)
super(settings)
- normal: (avg, std, n) =>
+ @normal_at: (avg, std, n) ->
assert(avg and std and n, string.format("normal(avg, std, n) called with %q %q %q", tostring(avg), tostring(std), tostring(n)))
-- Normal curve probability at N
(1/ (math.sqrt(2*math.pi) * avg)) * math.exp(-(n - avg)^2 / (2 * (std^2)))
+ @normal: (avg, std) =>
+ -- Box-Muller transform
+ bm = math.sqrt(-2 * math.log(math.random())) * math.cos(2 * math.pi * math.random())
+ -- Box-Muller gives us std = e^-0.5 , avg = 0
+ ((bm / math.exp(-1/2)) * std) + avg
poll: =>
@pump!
#@buffer > 0
send: (message) =>
-- Do we deliver?
- if @normal(@avg_loss, @loss_std, math.random()) < 0.5
+ rng = math.random()
+ if @loss > rng
return
-- How long does it take?
- time = @normal(@avg_latency, @latency_std, math.random())
+ -- Only uses the positive half of the normal distribution, double the standard deviation?
+ time = @@normal(@avg_latency, @latency_std * 2, math.random())
if time < 0 then
time = 0 -- We can't deliver messages in the past
- table.insert(@to_deliver, {message,time})
+ table.insert(@to_deliver, {message,@@time + time})
recv: =>
@pump!
table.remove(@buffer, 1)
@@ -62,11 +67,11 @@ class FaultyChannel extends Channel
deliver_len = #@to_deliver
for k,tbl in ipairs(@to_deliver)
{m, t} = tbl
+ @to_deliver[defrag] = tbl
if @@time > t
- @to_deliver[k] = nil
table.insert(@buffer, m)
- if @to_deliver[defrag] == nil
- @to_deliver[defrag] = tbl
+ else
+ defrag = defrag + 1
for i = defrag, deliver_len do
@to_deliver[i] = nil