Skip to content

Instantly share code, notes, and snippets.

@anacrolix
Created December 17, 2022 04:50
Show Gist options
  • Save anacrolix/3e5c7b89fe836ff41aec0e0fea8835bc to your computer and use it in GitHub Desktop.
Save anacrolix/3e5c7b89fe836ff41aec0e0fea8835bc to your computer and use it in GitHub Desktop.
local kwargs = {}
for i, k in ipairs(KEYS) do
kwargs[k] = table.remove(ARGV, 1)
end
local pop_kwargs = function (name, required)
local value = kwargs[name]
if value == nil then
if required then
error(string.format("missing key %q", name))
else
redis.log(
redis.LOG_NOTICE,
string.format("get peers key %q was not provided", name))
return nil
end
end
redis.log(
redis.LOG_NOTICE,
string.format("get peers key %q has value %q", name, value))
kwargs[name] = nil
return value
end
local info_hash = pop_kwargs('info_hash', true)
local max_last_got_peers = pop_kwargs('max_last_got_peers', true)
local new_last_got_peers = pop_kwargs('new_last_got_peers', true)
local remote = pop_kwargs('remote', true)
local max_peers = pop_kwargs('max_peers', false)
local min_peer_score = pop_kwargs('min_peer_score', true)
for k in pairs(kwargs) do
error({err='unexpected arg '..k})
end
if #ARGV ~= 0 then
return {err=string.format("%d trailing args", #ARGV)}
end
local get_peers = function (key)
redis.call('zremrangebyscore', key, '-inf', min_peer_score-1)
if max_peers then
return redis.call('zrandmember', key, max_peers)
else
return redis.call('zrange', key, 0, -1)
end
end
local last_got_peers_key = "last_got_peers:" .. info_hash
local seeders_key = "seeders:" .. info_hash
local leechers_key = "leechers:" .. info_hash
local last_got_peers = redis.call('zscore', last_got_peers_key, remote)
if last_got_peers and last_got_peers > max_last_got_peers then
max_peers = 0
end
local seeders = get_peers(seeders_key)
local leechers = get_peers(leechers_key)
if #seeders + #leechers > 0 then
redis.call('zadd', last_got_peers_key, new_last_got_peers, remote)
end
local leecher_count = redis.call('zcount', leechers_key, min_peer_score, "+inf")
local seeder_count = redis.call('zcount', seeders_key, min_peer_score, "+inf")
return {
seeders,
seeder_count,
leechers,
leecher_count,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment