Skip to content

Commit

Permalink
Update Lifetimes and Properties
Browse files Browse the repository at this point in the history
Performance of ThreadPools are now 5 times greater than previously.
  • Loading branch information
YetAnotherClown committed Mar 13, 2023
1 parent 7c9806c commit c0c4e95
Showing 1 changed file with 46 additions and 52 deletions.
98 changes: 46 additions & 52 deletions lib/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,6 @@
local ThreadPool = {}
ThreadPool.__index = ThreadPool

--[=[
@prop _openThreads { thread? }
@within ThreadPool
@private
@tag Internal Use Only
References to open threads.
]=]
ThreadPool._openThreads = {}

--[=[
@prop _threadCount number
@within ThreadPool
@private
@readonly
@tag Internal Use Only
The amount of threads to cache.
Negative numbers will enable Dynamic Caching, the Absolute Value of the property will always represent the minimum amount of threads that will be kept open.
]=]
ThreadPool._threadCount = 1

--[=[
@prop _cachedThreadLifetime number
@within ThreadPool
@private
@readonly
@tag Internal Use Only
The amount of seconds a thread will be kept alive after going idle.
]=]
ThreadPool._cachedThreadLifetime = 60

--[=[
@method _call
@within ThreadPool
Expand Down Expand Up @@ -97,28 +63,26 @@ end
]=]
function ThreadPool:_createThread()
local closeThread = false
local index = #self._openThreads + 1

-- Create new thread and add it to the openThreads table
local newThread: thread | nil
newThread = coroutine.create(function()
local lifetime = 0

while not closeThread do
local currentTick = os.clock()
self:_call(coroutine.yield())

-- Track lifetime
lifetime += os.clock() - currentTick

-- Implement cachedThreadLifetime
if lifetime >= self._cachedThreadLifetime then
closeThread = true
newThread = nil
self._openThreads[index] = nil
end
end
end)

-- Implement Lifetime
if #self._openThreads > self._threadCount then
local index = #self._openThreads + 1

task.delay(self._cachedThreadLifetime, function()
closeThread = true
newThread = nil
self._openThreads[index] = nil
end)
end

coroutine.resume(newThread :: thread)

table.insert(self._openThreads, newThread)
Expand Down Expand Up @@ -165,9 +129,39 @@ function ThreadPool.new(threadCount: number?, cachedThreadLifetime: number?)
local self = {}
setmetatable(self, ThreadPool)

-- Apply properties
self._threadCount = threadCount or self._threadCount
self._cachedThreadLifetime = cachedThreadLifetime or self._cachedThreadLifetime
--[=[
@prop _openThreads { thread? }
@within ThreadPool
@private
@tag Internal Use Only
References to open threads.
]=]
self._openThreads = {}

--[=[
@prop _threadCount number
@within ThreadPool
@private
@readonly
@tag Internal Use Only
The amount of threads to cache.
Negative numbers will enable Dynamic Caching, the Absolute Value of the property will always represent the minimum amount of threads that will be kept open.
]=]
self._threadCount = threadCount or 1

--[=[
@prop _cachedThreadLifetime number
@within ThreadPool
@private
@readonly
@tag Internal Use Only
The amount of seconds a thread will be kept alive after going idle.
]=]
self._cachedThreadLifetime = cachedThreadLifetime or 60 :: number?

-- Create initial new threads
for n = 1, math.abs(self._threadCount), 1 do
Expand All @@ -179,4 +173,4 @@ end

export type ThreadPool = typeof(ThreadPool.new())

return ThreadPool
return ThreadPool

0 comments on commit c0c4e95

Please sign in to comment.