Hello, I need to set a timeout on a function, to be able to return “took too long” when a function takes too long to finish. I’ve seen this can be done with events with something like Part.Touched:Wait(3)
where it will wait for a touch, or continue after 3 seconds. I need the samthing to be done with a normal function, not an event.
All help is appreciated.
I’m just a noob in learning :v
But maybe I would try to set a variable that increase its value each time the loop takes action, and set a conditional lock when the value reach certain amount…
local lock = true
local timeVal = 0
while lock do
print("doing stuff")
timeVal = timeVal + 1
if timeVal >= 30 then
lock = false
callFunction()
end
wait(1)
end
That would stop the function and make somekind of call after 30 seconds approx.
Surely would be better ideas xD
Yup this is a better idea :3
Actually looks like I didnt even understood the question xD
I have an idea
(this is the only way i think possible in Lua)
local timeout = 3
local didFinishFunction = false
function doThis()
-- do your function stuff
didFinishFunction = true -- make sure you put this at the very end of the function, this signifies that its been done
end
coroutine.wrap(doThis)()
local now = tick()
repeat wait() until didFinishFunction or tick() - now >= timeout
if not didFinishFunction then
print("Timeout!")
else
print("executed before three seconds!")
end
lol nvm, ExcessEnergy though of a much better method
o wait nvm it wont return out of the main function
(mine does work though)
This is a smart solution. I believe this should work great as long as you make sure to return.
if not didFinishFunction then
print("Timeout!")
return
else
print("executed before three seconds!")
return
end
Sorry that I kept confusing everybody with the overlook of return parentage.
local function RunFunc(func, args, timeout, timeoutCallback)
--RunFunc((Function)Function, (Table)Arguments, (Number)Timeout, (Optional-Table)TimeoutCallback)
--TimeoutCallback Table: {(Function)Function, (Table)Arguments, (Number)Attempts, (Number)Timeout}
-- or
--TimeoutCallback Table: {(String)"retry" or (String)"r", (Number)Attempts}
local StartTick = nil
local returned = nil
local newThread = coroutine.create(function()
if func then
local success, err = pcall(function()
if args then
StartTick = tick()
returned = func(args)
else
StartTick = tick()
returned = func()
end
end)
if not success then
warn(err)
end
end
end)
coroutine.resume(newThread)
repeat
wait()
until
coroutine.status(newThread) == "dead" or (tick() - StartTick) >= timeout
if (tick() - StartTick) >= timeout then
warn(tostring(func).." -> Timeout")
if timeoutCallback then
if tostring(timeoutCallback[1]):lower() == "retry" or tostring(timeoutCallback[1]):lower() == "r" then
if timeoutCallback[2] > 0 then
timeoutCallback[3] = timeoutCallback[2]
timeoutCallback[2] = args
timeoutCallback[1] = func
warn(tostring(func).." -> Timeout Callback Attempts Remaining: "..tostring(timeoutCallback[3]))
return RunFunc(timeoutCallback[1], timeoutCallback[2], timeout, {"retry", timeoutCallback[3]-1})
end
end
if timeoutCallback[3] then
if timeoutCallback[3] > 0 then
warn(tostring(func).." -> Timeout Callback Attempts Remaining: "..tostring(timeoutCallback[3]))
return RunFunc(timeoutCallback[1], timeoutCallback[2], timeoutCallback[4], {"retry", timeoutCallback[3]-1})
end
end
end
return {false}
else
return {true, returned}
end
end
local function cat(args)
print(args[1])
print(args[2])
local WaitTime = math.random(1,10)
print(WaitTime)
wait(WaitTime)
return args[1]..args[2]
end
--local x = RunFunc(cat, {"M1", "M2"}, 3, {cat, {"M1", "M2"}, 4, 4.1})
--local x = RunFunc(cat, {"M1", "M2"}, 5)
local x = RunFunc(cat, {"M1", "M2"}, 4.1, {"retry", math.random(4,7)})
if x[1] == false then
print("Function Timeout")
else
print("Success", x[2])
end
Could you give an example of the function you wanna “timeout”
I don’t know why, but @ExcessEnergy deleated his original post, which helped me solve my problem. What I did was something like this:
local timeout = 3
local timeoutEnded = false
spawn(function()
wait(timeout)
timeoutEnded = true
end)
while timeoutEnded == false do
--run function stuff here
end
@kylerzong’s may also work, but I haven’t tested it. (Also happy birthday, kylerzong! At the time i’m writing this it says it is your birthday)
Thanks Everyone!
Ooh, I’m glad my idea worked for you! I removed it after some scepticism of it working, since I was not on a device where I could test it out at the time of posting.
Happy birthday @kylerzong!