Skip to content

Commit

Permalink
refactor(client) moved metadata to its own cache (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tieske authored Aug 14, 2017
1 parent 53be3e8 commit fbc3087
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ History
### 0.6.x (xx-xxx-2017) Fixes and refactor

- Fix: fix an occasionally failing test
- Refactor: remove metadata from the records, instead store it in its own cache

### 0.6.1 (28-Jul-2017) Randomization adjusted

Expand Down
44 changes: 26 additions & 18 deletions src/resty/dns/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,6 @@ end
-- The `dnsCacheOnly` parameter found with `resolve` and `toip` can be used in
-- contexts where the co-socket api is unavailable. When the flag is set
-- only cached data is returned, but it will never use blocking io.
--
-- __Housekeeping__; when using `toip` it has to do some housekeeping to apply
-- the (weighted) round-robin scheme. Those values will be stored in the
-- dns record using field names starting with `__` (double underscores). So when
-- using `resolve` it might return a record from the cache with those fields if
-- it has been accessed by `toip` before.
-- @section resolving


Expand Down Expand Up @@ -1066,15 +1060,24 @@ local function resolve(qname, r_opts, dnsCacheOnly, try_list)
return nil, err, try_list
end

-- Create a metadata cache, using weak keys so it follows the dns record cache.
-- The cache will hold pointers and lists for (weighted) round-robin schemes
local metadataCache = setmetatable({}, { __mode = "k" })

-- returns the index of the record next up in the round-robin scheme.
local function roundRobin(rec)
local cursor = rec.__lastCursor or 0 -- start with first entry, trust the dns server! no random pick
local md = metadataCache[rec]
if not md then
md = {}
metadataCache[rec] = md
end
local cursor = md.lastCursor or 0 -- start with first entry, trust the dns server! no random pick
if cursor == #rec then
cursor = 1
else
cursor = cursor + 1
end
rec.__lastCursor = cursor
md.lastCursor = cursor
return cursor
end

Expand Down Expand Up @@ -1120,9 +1123,14 @@ end

-- returns the index of the SRV entry next up in the weighted round-robin scheme.
local function roundRobinW(rec)
local md = metadataCache[rec]
if not md then
md = {}
metadataCache[rec] = md
end

-- determine priority; stick to current or lower priority
local prioList = rec.__prioList -- list with indexes-to-entries having the lowest priority
local prioList = md.prioList -- list with indexes-to-entries having the lowest priority

if not prioList then
-- 1st time we're seeing this record, so go and
Expand All @@ -1142,21 +1150,21 @@ local function roundRobinW(rec)
weightList = { r.weight }
end
end
rec.__prioList = prioList
rec.__weightList = weightList
md.prioList = prioList
md.weightList = weightList
return prioList[1] -- start with first entry, trust the dns server!
end

local rrwList = rec.__rrwList
local rrwPointer = rec.__rrwPointer
local rrwList = md.rrwList
local rrwPointer = md.rrwPointer

if not rrwList then
-- 2nd time we're seeing this record
-- 1st time we trusted the dns server, now we do WRR by our selves, so
-- must create a list based on the weights. We do this only when necessary
-- for performance reasons, so only on 2nd or later calls. Especially for
-- ttl=0 scenarios where there is only 1 call ever.
local weightList = reducedWeights(rec.__weightList)
-- ttl=0 scenarios where there might only be 1 call ever.
local weightList = reducedWeights(md.weightList)
rrwList = {}
local x = 0
-- create a list of entries, where each entry is repeated based on its
Expand All @@ -1167,7 +1175,7 @@ local function roundRobinW(rec)
rrwList[x] = idx
end
end
rec.__rrwList = rrwList
md.rrwList = rrwList
-- The list has 2 parts, lower-part is yet to be used, higher-part was
-- already used. The `rrwPointer` points to the last entry of the lower-part.
-- On the initial call we served the first record, so we must rotate
Expand All @@ -1184,9 +1192,9 @@ local function roundRobinW(rec)
-- rotate to next
rrwList[idx], rrwList[rrwPointer] = rrwList[rrwPointer], rrwList[idx]
if rrwPointer == 1 then
rec.__rrwPointer = #rrwList
md.rrwPointer = #rrwList
else
rec.__rrwPointer = rrwPointer-1
md.rrwPointer = rrwPointer-1
end

return target
Expand Down

0 comments on commit fbc3087

Please sign in to comment.