mirror of
https://github.com/XeonSquared/OC-Copper.git
synced 2024-11-08 19:08:05 +11:00
Hopefully maybe implement the reliability layer.
This commit is contained in:
parent
aabbb554c6
commit
d63ba8db06
93
relib.lua
93
relib.lua
@ -11,25 +11,81 @@ local culib = require("culib")
|
|||||||
return function (hostname, transmit, onRReceive, time)
|
return function (hostname, transmit, onRReceive, time)
|
||||||
-- node.hostname should be used for hostname generally.
|
-- node.hostname should be used for hostname generally.
|
||||||
local node
|
local node
|
||||||
|
|
||||||
|
-- The maximum amount of timers (used to cap memory usage)
|
||||||
|
local tuningMaxTimers = 0x200
|
||||||
|
local tuningClearAntiduplicate = 120
|
||||||
|
local tuningAttempts = 8
|
||||||
|
local tuningAttemptTime = 4
|
||||||
|
|
||||||
|
-- Just an array, no special index.
|
||||||
|
-- Contents : {
|
||||||
|
-- trigger function,
|
||||||
|
-- expiry time
|
||||||
|
-- }
|
||||||
|
local timers = {}
|
||||||
|
-- Indexes are globalIds, values are timers for deleting entries out of this table.
|
||||||
|
local weAcked = {}
|
||||||
|
-- Indexes are globalIds, values are { successFunc, deathTimer }
|
||||||
|
local needsAck = {}
|
||||||
|
|
||||||
|
local function addTimer(trig, expi)
|
||||||
|
if #timers < tuningMaxTimers then
|
||||||
|
local t = {trig, expi}
|
||||||
|
table.insert(timers, t)
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local function killTimer(t)
|
||||||
|
for i = 1, #timers do
|
||||||
|
if timers[i] == t then
|
||||||
|
table.remove(timers, i)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function gen3Random()
|
||||||
|
return string.char(math.random(256) - 1) .. string.char(math.random(256) - 1) .. string.char(math.random(256) - 1)
|
||||||
|
end
|
||||||
|
local function genGlobalId(port)
|
||||||
|
local low = math.abs(math.floor(port)) % 256
|
||||||
|
local high = math.abs(math.floor(port / 256)) % 256
|
||||||
|
local portD = string.char(high) .. string.char(low)
|
||||||
|
return portD .. gen3Random()
|
||||||
|
end
|
||||||
|
|
||||||
local onReceive = function (nfrom, nto, data)
|
local onReceive = function (nfrom, nto, data)
|
||||||
if data:len() < 6 then return end
|
if data:len() < 6 then return end
|
||||||
local port = data:byte(2) + (data:byte(1) * 256)
|
local port = data:byte(2) + (data:byte(1) * 256)
|
||||||
if data:byte(7) == 0x0F then
|
local tp = data:byte(7)
|
||||||
|
local globalId = data:sub(1, 5)
|
||||||
|
if tp == 0x00 then
|
||||||
onRReceive(nfrom, nto, port, data, true)
|
onRReceive(nfrom, nto, port, data, true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
if nto ~= node.hostname then return end
|
||||||
|
if (tp == 0x01) and weAcked[nto .. globalId] then
|
||||||
|
-- Only send one acknowledgement per packet,
|
||||||
|
-- so timers aren't generated by external packets
|
||||||
|
-- Not a perfect system but, eh.
|
||||||
|
weAcked[nto .. globalId] = addTimer(function ()
|
||||||
|
weAcked[nto .. globalId] = nil
|
||||||
|
end, tuningClearAntiduplicate)
|
||||||
|
onRReceive(nfrom, nto, port, data, false)
|
||||||
|
node.output(nto, nfrom, data:sub(1, 6) .. "\x02")
|
||||||
|
end
|
||||||
|
if (tp == 0x02) and needsAck[nfrom .. globalId] then
|
||||||
|
needsAck[nfrom .. globalId][1](nfrom)
|
||||||
|
killTimer(needsAck[nfrom .. globalId][2])
|
||||||
|
needsAck[nfrom .. globalId] = nil
|
||||||
|
end
|
||||||
if nto ~= node.hostname then
|
if nto ~= node.hostname then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
node = culib(hostname, transmit, onReceive, time)
|
node = culib(hostname, transmit, onReceive, time)
|
||||||
|
|
||||||
-- Just an array, no special index.
|
|
||||||
-- Contents : {
|
|
||||||
-- trigger = function(),
|
|
||||||
-- expiry = time,
|
|
||||||
-- }
|
|
||||||
local timers = {}
|
|
||||||
local relib = {}
|
local relib = {}
|
||||||
relib.refresh = function ()
|
relib.refresh = function ()
|
||||||
node.refresh()
|
node.refresh()
|
||||||
@ -44,7 +100,26 @@ return function (hostname, transmit, onRReceive, time)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
relib.input = node.input
|
relib.input = node.input
|
||||||
relib.output = function ()
|
relib.output = function (nto, port, data, unreliable, onSucceed, onFailure)
|
||||||
|
local gid = genGlobalId(port)
|
||||||
|
if unreliable then
|
||||||
|
node.output(node.hostname, nto, gid .. "\x00\x00" .. data)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
local na = {onSucceed}
|
||||||
|
local attempt = -1
|
||||||
|
local doAttempt
|
||||||
|
doAttempt = function ()
|
||||||
|
attempt = attempt + 1
|
||||||
|
if attempt == tuningAttempts then
|
||||||
|
onFailure()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
node.output(node.hostname, nto, gid .. string.char(attempt) .. "\x01" .. data)
|
||||||
|
na[2] = addTimer(doAttempt, tuningAttemptTime)
|
||||||
|
end
|
||||||
|
needsAck[nto .. gid] = na
|
||||||
|
doAttempt()
|
||||||
|
end
|
||||||
|
return relib
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user