How To Set A Timout On A Function

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
1 Like

lol nvm, ExcessEnergy though of a much better method :stuck_out_tongue:
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.

1 Like
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!