From feccac3d7d536f5b0f056cfd169340139ec52a58 Mon Sep 17 00:00:00 2001 From: _AMD_ Date: Wed, 8 Jan 2025 15:56:14 +0300 Subject: [PATCH] minor changes --- examples/advanced/client.lua | 62 +++++++++++++----------- lua/long-polling/dataproviders/redis.lua | 8 ++- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/examples/advanced/client.lua b/examples/advanced/client.lua index a8188cc..9a3ea8c 100644 --- a/examples/advanced/client.lua +++ b/examples/advanced/client.lua @@ -1,5 +1,4 @@ --- source: https://github.com/TRIGONIM/lua-long-polling/blob/e28fff8141c7d1a22e030c9d6132ef853032da84/lua/long-polling/client.lua --- local kupol = require("long-polling.client") +-- local kupol = require("kupol.client") -- local Client = kupol.new("https://lp.example.com/channel") -- By default, client use copas and lua-cjson, but you can use your own functions -- from Garry's Mod for example @@ -41,36 +40,45 @@ function MT:handle_error(err) self:log("🆘 Error\n\t%s", err) end +function MT:on_data_received(tData) + local on_update = self.on_update + if not on_update then self:log("🆘 No handler callback provided") return end + + for _, update in ipairs(tData.updates) do + local pcallok, res = pcall(on_update, update, tData.ts) + if not pcallok then + self:log(debug.traceback("🆘 Kupol Error In The Handler Callback\n\t%s"), res) + end + end +end + +local function log_if_lost_updates(updates_num, offset_requested, offset_remote) + offset_requested = offset_requested or 0 + + local updates_expected = offset_remote - offset_requested + + -- REMOTE FUCKUP. e.g. remote ts 0, local ts 1000 + -- e.g. lpolling database wiped + if updates_expected < 0 then + self:log("🚧 ts on server is less than requested (%d < %d)", offset_remote, offset_requested) + + -- LOCAL FUCKUP. e.g. remote ts 100, local ts 0, but 30 updates instead of 100 + -- e.g. too long time haven't requested updates + elseif updates_expected ~= updates_num then + self:log("🚧 updates lost: %d (got %d, expected %d)", updates_expected - updates_num, updates_num, updates_expected) + end +end + function MT:subscribe(fHandler, requested_ts, timeout) + self.on_update = fHandler + self.thread = kupol.thread_new(function() repeat local tmt = requested_ts and timeout or 0 -- it's better if first request will be fast if requested_ts not provided local tData, body = self:get(requested_ts, tmt) if tData then - local ts_diff = tData.ts - (requested_ts or 0) - - local REM = (requested_ts or 0) > tData.ts -- REMOTE FUCKUP. e.g. remote ts 0, local ts 1000 - local LOC = ts_diff > #tData.updates -- LOCAL FUCKUP. e.g. remote ts 100, local ts 0, but 30 updates instead of 100 - if REM or LOC then - if REM then - self:log("🚧 ts on server is less than requested (%d < %d)", tData.ts, requested_ts) - end - - if LOC then - self:log("🚧 updates lost: %d (got %d, expected %d)", ts_diff - #tData.updates, #tData.updates, ts_diff) -- too long time haven't requested them - end - - requested_ts = tData.ts -- emerg reset - else - requested_ts = requested_ts and (requested_ts + #tData.updates) or tData.ts - -- requested_ts = tData.ts - end - - for _, update in ipairs(tData.updates) do - local pcallok, res = pcall(fHandler, update, tData.ts) - if not pcallok then - self:log(debug.traceback("🆘 Kupol Error In The Handler Callback\n\t%s"), res) - end - end + log_if_lost_updates(#tData.updates, requested_ts, tData.ts) + self:on_data_received(tData) + requested_ts = tData.ts else -- no tData self:handle_error(body) kupol.thread_pause(10) diff --git a/lua/long-polling/dataproviders/redis.lua b/lua/long-polling/dataproviders/redis.lua index 1b4a5f6..82c6d12 100644 --- a/lua/long-polling/dataproviders/redis.lua +++ b/lua/long-polling/dataproviders/redis.lua @@ -3,6 +3,10 @@ local rds = require("long-polling.misc.redis-safe") local MT = {} MT.__index = MT +-- Новый запрос - новое соединение. Спам выходит, но не очень критично. +-- Переиспользовать нельзя. +-- Потому что в многопотоке сбивается порядок чтение-запись с редиса и начинаются ошибки. +-- Такая особенность либы. Например в JS либа реализована так, что в одном "потоке" идет запись, а в другом - чтение. function MT:getcon() local opts = self.opts.redis return rds.create(opts.own and opts or { @@ -63,10 +67,10 @@ function MT:add_update(channel, data) local total_key = prefix .. "total:" .. channel local updates_key = prefix .. "updates:" .. channel - local result = redis:eval(script, 2, total_key, updates_key, data, ttl, max_updates) + local new_total = redis:eval(script, 2, total_key, updates_key, data, ttl, max_updates) redis:quit() - return result + return new_total end function MT.new(opts)