SyntaxGameServer/RCCService2021/ExtraContent/LuaPackages/AppTempCommon/LuaApp/Utils/FetchSubdividedThumbnails.lua

139 lines
4.6 KiB
Lua

local CorePackages = game:GetService("CorePackages")
local LuaApp = CorePackages.AppTempCommon.LuaApp
local ArgCheck = require(CorePackages.ArgCheck)
local Thumbnail = require(LuaApp.Models.Thumbnail)
local PerformFetch = require(LuaApp.Thunks.Networking.Util.PerformFetch)
local Promise = require(LuaApp.Promise)
local Result = require(LuaApp.Result)
local TableUtilities = require(LuaApp.TableUtilities)
local RETRY_MAX_COUNT = math.max(0, settings():GetFVariable("LuaAppNonFinalThumbnailMaxRetries"))
local RETRY_TIME_MULTIPLIER = math.max(0, settings():GetFVariable("LuaAppThumbnailsApiRetryTimeMultiplier")) -- seconds
local FetchSubdividedThumbnails = {}
function FetchSubdividedThumbnails._fetchIcons(store, networkImpl, targetIds, iconSize, keyMapper, requestName, fetchFunction, storeDispatch)
local function keyMapperForCurrentRequestNameAndSize(targetId)
return keyMapper({
targetId = targetId,
requestName = requestName,
iconSize = iconSize
})
end
local function getTableOfFailedResults(failedTargetIds)
local results = {}
for _, targetId in pairs(failedTargetIds) do
local key = keyMapperForCurrentRequestNameAndSize(targetId)
results[key] = Result.new(false, {
targetId = targetId,
})
end
return results
end
return fetchFunction(networkImpl, targetIds, iconSize):andThen(
function(result)
local results = getTableOfFailedResults(targetIds)
local validIcons = {}
local data = result and result.responseBody and result.responseBody.data
if typeof(data) == "table" then
for _, iconInfo in pairs(data) do
if Thumbnail.isCompleteThumbnailData(iconInfo) then
local targetId = tostring(iconInfo.targetId)
local success = false
if Thumbnail.checkStateIsFinal(iconInfo.state) then
validIcons[targetId] = Thumbnail.fromThumbnailData(iconInfo, iconSize)
success = true
end
results[keyMapperForCurrentRequestNameAndSize(targetId)] = Result.new(success, iconInfo)
end
end
end
store:dispatch(storeDispatch(validIcons))
return Promise.resolve(results)
end,
function(err)
local results = getTableOfFailedResults(targetIds)
return Promise.resolve(results)
end
)
end
function FetchSubdividedThumbnails._fetch(store, networkImpl, targetIds, size, keyMapper, requestName, fetchFunction, storeDispatch)
return FetchSubdividedThumbnails._fetchIcons(store, networkImpl, targetIds, size, keyMapper, requestName, fetchFunction, storeDispatch)
:andThen(function(results)
local completedIcons = {}
local iconResults = results
if _G.__TESTEZ_RUNNING_TEST__ then
RETRY_MAX_COUNT = 1
RETRY_TIME_MULTIPLIER = 0.001
end
local function retry(retryCount)
local remainingUnfinalizedIcons = {}
for k, result in pairs(iconResults) do
local isSuccessful, iconInfo = result:unwrap()
-- Retry icon request for targetId that failed.
if isSuccessful and Thumbnail.checkStateIsFinal(iconInfo.state) then
completedIcons[k] = result
else
table.insert(remainingUnfinalizedIcons, iconInfo)
end
end
if TableUtilities.FieldCount(remainingUnfinalizedIcons) == 0 then
--All requests are successful
return Promise.resolve(completedIcons)
end
local delayPromise = Promise.new(function(resolve, reject)
coroutine.wrap(function()
wait(RETRY_TIME_MULTIPLIER * math.pow(2, retryCount - 1))
resolve()
end)()
end)
return delayPromise:andThen(function()
return FetchSubdividedThumbnails._fetchIcons(store, networkImpl,
targetIds, size, keyMapper, requestName, fetchFunction, storeDispatch)
end):andThen(function(newResults)
iconResults = newResults
if retryCount > 1 then
return retry(retryCount - 1)
else
return Promise.resolve(completedIcons)
end
end)
end
return retry(RETRY_MAX_COUNT)
end)
end
function FetchSubdividedThumbnails.Fetch(networkImpl, requests, keyMapper, requestName, fetchFunction, storeDispatch)
ArgCheck.isType(requests, "table", "requests")
ArgCheck.isType(requestName, "string", "requestName")
ArgCheck.isNonNegativeNumber(#requests, "requests count")
FetchSubdividedThumbnails.KeyMapper = keyMapper
return PerformFetch.Batch(requests, keyMapper, function(store, filteredrequests)
local targetIdsNeeded = {}
local size
-- Filter out the icons that are already in the store.
for _, request in ipairs(filteredrequests) do
local targetId = request.targetId
size = request.iconSize
table.insert(targetIdsNeeded, targetId)
end
return FetchSubdividedThumbnails._fetch(store, networkImpl, targetIdsNeeded, size, keyMapper, requestName, fetchFunction, storeDispatch)
end)
end
return FetchSubdividedThumbnails