feat: implement resilient task wrapper for parallel tasks to enhance stability

This commit is contained in:
MayaTheShy
2026-03-25 21:53:47 -04:00
parent 62a9ab811d
commit b3a69c6797

View File

@@ -350,13 +350,35 @@ local function main()
end
print("")
-----------------------------------------------
-- Resilient task wrapper: if a task crashes, it
-- restarts after a brief delay instead of killing
-- all other parallel tasks.
-----------------------------------------------
local function resilient(name, fn)
return function()
while true do
local ok, err = pcall(fn)
if not ok then
log.error("TASK", "%s crashed: %s", name, tostring(err))
sleep(5)
log.info("TASK", "%s restarting...", name)
else
-- Task returned normally (shouldn't happen)
log.warn("TASK", "%s exited unexpectedly, restarting...", name)
sleep(1)
end
end
end
end
-----------------------------------------------
-- Parallel tasks
-----------------------------------------------
parallel.waitForAny(
-- Task 1: Background inventory scanner
function()
resilient("Scanner", function()
if cacheLoaded then
pcall(ops.refreshCache)
pcall(ops.checkAlerts)
@@ -373,18 +395,18 @@ local function main()
state.needsRedraw = true
state.smelterNeedsRedraw = true
end
end,
end),
-- Task 2: Barrel auto-sort
function()
resilient("Barrel-sort", function()
while true do
pcall(ops.sortBarrel)
sleep(cfg.POLL_INTERVAL)
end
end,
end),
-- Task 3: Auto-smelt
function()
resilient("Auto-smelt", function()
while true do
local ok, didWork = pcall(ops.autoSmelt)
if ok and didWork then
@@ -398,10 +420,10 @@ local function main()
state.smelterNeedsRedraw = true
sleep(cfg.SMELT_INTERVAL)
end
end,
end),
-- Task 4: Defrag (consolidate partial stacks)
function()
resilient("Defrag", function()
sleep(10)
while true do
activity.defragging = true
@@ -411,10 +433,10 @@ local function main()
state.needsRedraw = true
sleep(cfg.DEFRAG_INTERVAL)
end
end,
end),
-- Task 5: Auto-compost
function()
resilient("Auto-compost", function()
while true do
activity.composting = true
state.needsRedraw = true
@@ -424,10 +446,10 @@ local function main()
pcall(ops.checkAlerts)
sleep(cfg.COMPOST_INTERVAL)
end
end,
end),
-- Task 5b: Auto-discard excess stock
function()
resilient("Auto-discard", function()
if #cfg.TRASH_DROPPERS == 0 then
while true do sleep(3600) end
end
@@ -441,10 +463,10 @@ local function main()
state.needsRedraw = true
sleep(cfg.DISCARD_INTERVAL)
end
end,
end),
-- Task 5c: Auto-craft excess items into target products
function()
resilient("Auto-craft", function()
sleep(12) -- let initial scan + discard settle first
log.info("AUTOCRAFT", "Auto-craft active (%d explicit rule(s), smart=%s)",
#cfg.AUTO_CRAFT_RULES, tostring(cfg.AUTO_CRAFT_FROM_EXCESS))
@@ -458,10 +480,23 @@ local function main()
end
sleep(cfg.AUTO_CRAFT_INTERVAL)
end
end,
end),
-- Task 5d: Collection hopper emptying (egg spawner, etc.)
resilient("Hopper-collect", function()
if #cfg.COLLECTION_HOPPERS == 0 then
while true do sleep(3600) end
end
sleep(3)
log.info("COLLECT", "Hopper collection active for %d hopper(s)", #cfg.COLLECTION_HOPPERS)
while true do
pcall(ops.collectHoppers)
sleep(cfg.COLLECTION_INTERVAL)
end
end),
-- Task 6: Low-stock alert checker
function()
resilient("Alert-checker", function()
sleep(5)
pcall(ops.checkAlerts)
state.needsRedraw = true
@@ -470,10 +505,10 @@ local function main()
pcall(ops.checkAlerts)
state.needsRedraw = true
end
end,
end),
-- Task 7: Main dashboard redraw (event-driven, polls 0.1s)
function()
resilient("Dashboard", function()
state.needsRedraw = true
while true do
if state.needsRedraw then
@@ -493,10 +528,10 @@ local function main()
end
sleep(0.1)
end
end,
end),
-- Task 8: Smelter dashboard redraw
function()
resilient("Smelter-dashboard", function()
state.smelterNeedsRedraw = true
while true do
if state.smelterNeedsRedraw then
@@ -506,10 +541,10 @@ local function main()
end
sleep(0.1)
end
end,
end),
-- Task 9: Touch event listener (both monitors)
function()
resilient("Touch-listener", function()
while true do
local event, side, x, y = os.pullEvent("monitor_touch")
if display.smelterMonName and side == display.smelterMonName then
@@ -520,20 +555,20 @@ local function main()
display.handleTouch(x, y)
end
end
end,
end),
-- Task 10: Network state broadcast (skips if nothing changed)
function()
resilient("Broadcast", function()
while true do
if state.stateVersion ~= state.lastBroadcastVersion then
pcall(broadcastState)
end
sleep(cfg.BROADCAST_INTERVAL)
end
end,
end),
-- Task 11: Peripheral detach handler
function()
resilient("Detach-handler", function()
while true do
local event, name = os.pullEvent("peripheral_detach")
if name then
@@ -546,10 +581,10 @@ local function main()
end
end
end
end,
end),
-- Task 11b: Peripheral attach handler (auto-detect crafting turtle)
function()
resilient("Attach-handler", function()
while true do
local event, name = os.pullEvent("peripheral_attach")
if name and name:match("^turtle_") and not ctx.craftTurtleName then
@@ -558,10 +593,10 @@ local function main()
pcall(broadcastState)
end
end
end,
end),
-- Task 12: Supply chest (builder / manifest-based stocking)
function()
resilient("Supply-chest", function()
if cfg.SUPPLY_CHEST == "" or #cfg.SUPPLY_MANIFEST == 0 then
while true do sleep(3600) end
end
@@ -570,10 +605,10 @@ local function main()
pcall(ops.supplyChest)
sleep(cfg.SUPPLY_INTERVAL)
end
end,
end),
-- Task 13: Network order/command listener
function()
resilient("Network-listener", function()
if not ctx.networkModem then
while true do sleep(3600) end
end
@@ -832,7 +867,7 @@ local function main()
end -- idempotency else
end
end
end
end)
)
end