fix(rbxl): watchdog 100k→20k + откат pcall(yield) + batch 5+20ms
Прошлый коммит pcall(coroutine.yield) дал бесконечный цикл: yield внутри C-call падал → pcall ловил → hook возвращался → счётчик не сбросился → срабатывал опять моментально → вис. Новая стратегия: 1. Голый coroutine.yield в watchdog: если внутри C-call упадёт с ошибкой — pcall(fn,...) внутри coroutine её поймает, скрипт завершится. Лучше чем вис. 2. Frequency 100k→20k инструкций — yield чаще, меньше времени на tight-loop перед уступкой управления UI. 3. Batch kickoff 20→5 скриптов с delay 20мс (было 0). 55 скриптов ROBLOX Battle = ~200мс распределено, UI отзывается. Page-hang при init должен исчезнуть. Скрипты с tight-loop типа WaitForChild через ChildAdded:wait() упадут с ошибкой про yield, но не повесят страницу.
This commit is contained in:
parent
734521df72
commit
38d135586b
@ -115,8 +115,8 @@ export class LuaSharedSandbox {
|
|||||||
// Запускаем main-loop сразу — он начнёт tick'ать как только будут coroutines.
|
// Запускаем main-loop сразу — он начнёт tick'ать как только будут coroutines.
|
||||||
this._lastTickAt = performance.now();
|
this._lastTickAt = performance.now();
|
||||||
this._startMainLoop();
|
this._startMainLoop();
|
||||||
// Init батчами по 20 с yield между ними, чтобы UI не подвисал на 700+ скриптах.
|
// Init батчами по 5 с задержкой 20мс между ними, чтобы UI отзывался.
|
||||||
const BATCH_SIZE = 20;
|
const BATCH_SIZE = 5;
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
const initBatch = () => {
|
const initBatch = () => {
|
||||||
if (this._isStopped) return;
|
if (this._isStopped) return;
|
||||||
@ -130,7 +130,7 @@ export class LuaSharedSandbox {
|
|||||||
}
|
}
|
||||||
idx = end;
|
idx = end;
|
||||||
if (idx < pending.length) {
|
if (idx < pending.length) {
|
||||||
setTimeout(initBatch, 0);
|
setTimeout(initBatch, 20);
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`[LuaSharedSandbox] all ${pending.length} scripts kicked off`);
|
console.log(`[LuaSharedSandbox] all ${pending.length} scripts kicked off`);
|
||||||
@ -199,13 +199,11 @@ export class LuaSharedSandbox {
|
|||||||
})
|
})
|
||||||
local co = coroutine.create(function()
|
local co = coroutine.create(function()
|
||||||
-- WATCHDOG: каждые 100000 инструкций — yield 1 кадр.
|
-- WATCHDOG: каждые 100000 инструкций — yield 1 кадр.
|
||||||
-- Защищает от tight-loop. yield обёрнут в pcall так как
|
-- НЕ оборачиваем в pcall — внутри C-call boundary yield
|
||||||
-- внутри C-call boundary yield бросает ошибку — но в этом
|
-- упадёт ошибкой, что прервёт скрипт. Это лучше чем виснуть.
|
||||||
-- случае tight-loop наш hook просто будет вызываться позже
|
|
||||||
-- (когда Lua вернётся из C-call) и yield сработает.
|
|
||||||
debug.sethook(function()
|
debug.sethook(function()
|
||||||
pcall(coroutine.yield, 0.016)
|
coroutine.yield(0.016)
|
||||||
end, "", 100000)
|
end, "", 20000)
|
||||||
-- pcall защищает от runtime-ошибок которые иначе крашат
|
-- pcall защищает от runtime-ошибок которые иначе крашат
|
||||||
-- coroutine и могут повредить WASM-стейт. Возвраты
|
-- coroutine и могут повредить WASM-стейт. Возвраты
|
||||||
-- handler'а намеренно поглощаются.
|
-- handler'а намеренно поглощаются.
|
||||||
|
|||||||
@ -1642,11 +1642,9 @@ export function registerRobloxShim(lua, opts) {
|
|||||||
-- (ok, ret1, ret2, ...) — мы их не используем.
|
-- (ok, ret1, ret2, ...) — мы их не используем.
|
||||||
local co = coroutine.create(function()
|
local co = coroutine.create(function()
|
||||||
-- Тот же watchdog что и в _startSingleScript.
|
-- Тот же watchdog что и в _startSingleScript.
|
||||||
-- yield обёрнут в pcall: внутри C-call boundary yield бросает
|
|
||||||
-- ошибку, но hook будет вызван позже когда Lua вернётся.
|
|
||||||
debug.sethook(function()
|
debug.sethook(function()
|
||||||
pcall(coroutine.yield, 0.016)
|
coroutine.yield(0.016)
|
||||||
end, "", 100000)
|
end, "", 20000)
|
||||||
pcall(fn, a1, a2, a3, a4)
|
pcall(fn, a1, a2, a3, a4)
|
||||||
end)
|
end)
|
||||||
__rbxl_register_coroutine(handlerId, co)
|
__rbxl_register_coroutine(handlerId, co)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user