Skip to content

Commit 6fe41c6

Browse files
committed
Better SV chunking + handle data request concurrency
1 parent f47d243 commit 6fe41c6

File tree

3 files changed

+103
-16
lines changed

3 files changed

+103
-16
lines changed

lua/autorun/blobsprofiler_autorun.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ blobsProfiler.Server = blobsProfiler.Server or {}
77
blobsProfiler.Client.Profile = blobsProfiler.Client.Profile or {}
88
blobsProfiler.Server.Profile = blobsProfiler.Server.Profile or {}
99

10+
blobsProfiler.svDataChunkSize = 15000
11+
1012
local realmDataTable = {}
1113

1214
if SERVER then

lua/blobsprofiler/client/cl_blobsprofiler.lua

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ local function nodeEntriesTableKeySort(a, b)
607607
elseif !aIsTable && bIsTable then
608608
return false
609609
else
610-
return a.key < b.key
610+
return tostring(a.key) < tostring(b.key) -- Just in case.. (It's here for a reason :))
611611
end
612612
end
613613

@@ -1313,10 +1313,20 @@ concommand.Add("blobsprofiler", function(ply, cmd, args, argStr)
13131313
end
13141314
end
13151315
subModuleTab.PaintOver = function(s,w,h)
1316-
if subModuleData.retrievingData then
1316+
if luaState == "Server" and subModuleData.retrievingData then
13171317
surface.SetDrawColor(50,50,50,100)
13181318
surface.DrawRect(0,0,w,h)
13191319
draw.SimpleTextOutlined("Retrieving data..", "HudDefault", w/2, h/2, Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(0,0,0))
1320+
1321+
local subModuleFullName = moduleName .. "." .. subModuleName
1322+
if blobsProfiler.chunkModuleData[subModuleFullName] and blobsProfiler.chunkModuleData[subModuleFullName].receivedChunks then
1323+
local recvChunks = #blobsProfiler.chunkModuleData[subModuleFullName].receivedChunks
1324+
local totChunks = blobsProfiler.chunkModuleData[subModuleFullName].totalChunks
1325+
1326+
if recChunks ~= totChunks then
1327+
draw.SimpleTextOutlined(recvChunks.. "/" .. totChunks, "HudDefault", w/2, h/2+15, Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(0,0,0))
1328+
end
1329+
end
13201330
end
13211331
end
13221332

@@ -1341,10 +1351,19 @@ concommand.Add("blobsprofiler", function(ply, cmd, args, argStr)
13411351
end
13421352

13431353
moduleTab.PaintOver = function(s,w,h)
1344-
if moduleData.retrievingData then
1354+
if luaState == "Server" and moduleData.retrievingData then
13451355
surface.SetDrawColor(50,50,50,100)
13461356
surface.DrawRect(0,0,w,h)
1347-
draw.SimpleTextOutlined("Retrieving data..", "HudDefault", w/2, h/2, Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(0,0,0))
1357+
draw.SimpleTextOutlined("Retrieving data..", "HudDefault", w/2, h/2-15, Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(0,0,0))
1358+
1359+
if blobsProfiler.chunkModuleData[moduleName] and blobsProfiler.chunkModuleData[moduleName].receivedChunks then
1360+
local recvChunks = #blobsProfiler.chunkModuleData[moduleName].receivedChunks
1361+
local totChunks = blobsProfiler.chunkModuleData[moduleName].totalChunks
1362+
1363+
if recChunks ~= totChunks then
1364+
draw.SimpleTextOutlined(recvChunks.. "/" .. totChunks, "HudDefault", w/2, h/2+15, Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(0,0,0))
1365+
end
1366+
end
13481367
end
13491368
end
13501369

@@ -1396,7 +1415,7 @@ concommand.Add("blobsprofiler", function(ply, cmd, args, argStr)
13961415
tabMenu:OnActiveTabChanged(nil, tabMenu:GetActiveTab()) -- lol
13971416
end)
13981417

1399-
netstream.Hook("blobsProfiler:requestData", function(rawModuleName, rawDataTable)
1418+
local function handleSVDataUpdate(rawModuleName, dataTable)
14001419
local moduleSplit = string.Explode(".", rawModuleName) -- [1] is parent, [2] is submodule
14011420
local moduleName = moduleSplit[1]
14021421
local subModule = nil
@@ -1406,15 +1425,6 @@ netstream.Hook("blobsProfiler:requestData", function(rawModuleName, rawDataTable
14061425
if #moduleSplit == 2 then -- ew
14071426
subModule = moduleSplit[2]
14081427
end
1409-
1410-
local decompressedData = util.Decompress(rawDataTable)
1411-
if not decompressedData then
1412-
blobsProfiler.Log(blobsProfiler.L_ERROR, "Failed to decompress SV data for: "..rawModuleName)
1413-
end
1414-
local dataTable = util.JSONToTable(decompressedData)
1415-
if not dataTable then
1416-
blobsProfiler.Log(blobsProfiler.L_ERROR, "Failed to deserialise SV data for: "..rawModuleName)
1417-
end
14181428

14191429
if not subModule then
14201430
if blobsProfiler.Modules[moduleName] then
@@ -1437,6 +1447,35 @@ netstream.Hook("blobsProfiler:requestData", function(rawModuleName, rawDataTable
14371447
end
14381448
end
14391449
end
1450+
end
1451+
1452+
blobsProfiler.chunkModuleData = {}
1453+
1454+
net.Receive("blobsProfiler:requestData", function()
1455+
local moduleName = net.ReadString()
1456+
local totalChunks = net.ReadUInt(16)
1457+
local currentChunk = net.ReadUInt(16)
1458+
local chunkData = net.ReadData(blobsProfiler.svDataChunkSize)
1459+
1460+
if not blobsProfiler.chunkModuleData[moduleName] then
1461+
blobsProfiler.chunkModuleData[moduleName] = {
1462+
totalChunks = totalChunks,
1463+
receivedChunks = {},
1464+
}
1465+
end
1466+
1467+
if not blobsProfiler.chunkModuleData[moduleName].receivedChunks then
1468+
blobsProfiler.chunkModuleData[moduleName].receivedChunks = {}
1469+
end
1470+
1471+
table.insert(blobsProfiler.chunkModuleData[moduleName].receivedChunks, chunkData)
1472+
1473+
if #blobsProfiler.chunkModuleData[moduleName].receivedChunks == totalChunks then
1474+
local fullData = table.concat(blobsProfiler.chunkModuleData[moduleName].receivedChunks)
1475+
blobsProfiler.chunkModuleData[moduleName] = util.JSONToTable(util.Decompress(fullData))
1476+
1477+
handleSVDataUpdate(moduleName, blobsProfiler.chunkModuleData[moduleName])
1478+
end
14401479
end)
14411480

14421481
blobsProfiler.buildDTree = buildDTree

lua/blobsprofiler/server/sv_blobsprofiler.lua

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,50 @@ net.Receive("blobsProfiler:requestSource", function(l, ply)
6363
SendChunkedString(ply, requestID, combinedSource)
6464
end)
6565

66+
local transmissionStates = {}
67+
68+
local function sendDataToClient(ply, moduleName, dataTbl)
69+
if transmissionStates[ply] and transmissionStates[ply][moduleName] then
70+
return
71+
end
72+
73+
local data = util.Compress(util.TableToJSON(dataTbl))
74+
local totalChunks = math.ceil(#data / blobsProfiler.svDataChunkSize)
75+
76+
transmissionStates[ply] = transmissionStates[ply] or {}
77+
transmissionStates[ply][moduleName] = {
78+
data = data,
79+
totalChunks = totalChunks,
80+
currentChunk = 1
81+
}
82+
83+
local function sendNextChunk()
84+
if not IsValid(ply) then return end
85+
local state = transmissionStates[ply][moduleName]
86+
if not state then return end
87+
88+
local startIdx = (state.currentChunk - 1) * blobsProfiler.svDataChunkSize + 1
89+
local endIdx = math.min(startIdx + blobsProfiler.svDataChunkSize - 1, #state.data)
90+
local chunk = string.sub(state.data, startIdx, endIdx)
91+
92+
net.Start("blobsProfiler:requestData")
93+
net.WriteString(moduleName)
94+
net.WriteUInt(state.totalChunks, 16)
95+
net.WriteUInt(state.currentChunk, 16)
96+
net.WriteData(chunk, #chunk)
97+
net.Send(ply)
98+
99+
state.currentChunk = state.currentChunk + 1
100+
if state.currentChunk > state.totalChunks then
101+
transmissionStates[ply][moduleName] = nil
102+
else
103+
timer.Simple(0.1, sendNextChunk)
104+
end
105+
end
106+
107+
sendNextChunk()
108+
end
109+
66110
net.Receive("blobsProfiler:requestData", function(l, ply)
67111
if not blobsProfiler.CanAccess(ply, "serverData") then return end
68112
blobsProfiler.Log(blobsProfiler.L_DEBUG, "requestData NW")
@@ -100,7 +144,9 @@ net.Receive("blobsProfiler:requestData", function(l, ply)
100144
dataTbl = {}
101145
end
102146

103-
dataTbl = util.Compress(util.TableToJSON(dataTbl))
104-
netstream.Heavy(ply, "blobsProfiler:requestData", rawDataModule, dataTbl)
147+
--dataTbl = util.Compress(util.TableToJSON(dataTbl))
148+
--netstream.Heavy(ply, "blobsProfiler:requestData", rawDataModule, dataTbl)
149+
sendDataToClient(ply, rawDataModule, dataTbl)
150+
105151
blobsProfiler.Log(blobsProfiler.L_DEBUG, "Module: ".. rawDataModule .." data sent to client!")
106152
end)

0 commit comments

Comments
 (0)