Hi, i’m working on making my own observer pattern module, but it’s not important, the important thing is that i need to run function in coroutine, and when it finishes, remove it from a table
function Connection:run()
local thread
thread = task.spawn(function()
self.Callbakc()
local index = table.find(self.Threads, thread)
if index then
table.remove(self.Threads, index)
end
end)
table.insert(self.Threads, thread)
end
This is where problem starts, it causes memory leak because thread cannot be removed sometimes, and when it’s left in table, it stucks, any idea how to fix it or have something like that functionality?
task.spawn() will run the function immediately, so it will call self.Callback(). and if that callback is not yielding, then it will continue to find the thread in table. but at this point, the thread is not inserted.
after that, the thread is inserted
function __Thread:start(Callback, ...)
self.Thread = task.defer(function(...)
Callback(...)
self:destroy()
end, ...)
if self.Connection then
table.insert(self.Connection.Threads, self.Thread)
end
end
If callback yields, it will cause memory leak
destroy methood:
function __Thread:destroy()
if self.Connection then
local ThreadIndex = table.find(self.Connection.Threads, self.Thread)
if ThreadIndex then
table.remove(self.Connection.Threads, ThreadIndex)
end
self.Connection = nil
end
if self.Thread then
coroutine.yield(self.Thread)
coroutine.close(self.Thread)
self.Thread = nil
end
self.IsRunning = nil
setmetatable(self, nil)
table.freeze(self)
end
i think nothing to do with using coroutine or not,
self.Connection.Threads is a table, its intention is to hold multiple threads,
so we would assume we can call start() multiple times for different callbacks and then they’ll self clean up.
however, we only have ONE self.Thread , and then rely on that single entry to find itself. then all other threads are lost.
It turns out, after a test, that it might not be memory leak but rather registry optimization, there is similar behvaior in tables, i tried running connection 100 times (and also run 100 threads) twice, registry only grew once, later it became stable
I’m afraid that this optimization might cause some issues in the future, but if threads will be used sparingly then it wouldn’t do that much, anyways thx for help