Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
YetAnotherClown committed Mar 12, 2023
0 parents commit 7c9806c
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Roblox Studio lock files
/*.rbxlx.lock
/*.rbxl.lock
/*.rbxm
/build
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Clownxz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ThreadPool

<a href="https://clownxz.github.io/ThreadPool/"><strong>View docs</strong></a>

A library for creating Thread Pools to improve performance and reduce latency.

---

#### Thread Pooling
Thread Pooling reuses already existing threads instead of creating new threads every time you need to use one.

#### Why use this?
You shouldn't need to, unless you are creating multiple threads at a given time.

#### Usage
```lua
local ThreadPool = Require(path.to.module)

local myThreadPool = ThreadPool.new()

myThreadPool:spawn(function(...)
print(...) -- Prints "Hello World"
end, "Hello, world!")
```

---

#### Building with Rojo

To build yourself, use:
```bash
rojo build -o "ThreadPool.rbxm"
```

For more help, check out [the Rojo documentation](https://rojo.space/docs).
7 changes: 7 additions & 0 deletions aftman.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file lists tools managed by Aftman, a cross-platform toolchain manager.
# For more information, see https://github.com/LPGhatguy/aftman

# To add a new tool, add an entry to this table.
[tools]
rojo = "rojo-rbx/[email protected]"
# rojo = "rojo-rbx/[email protected]"
6 changes: 6 additions & 0 deletions default.project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "ThreadPool",
"tree": {
"$path": "lib"
}
}
182 changes: 182 additions & 0 deletions lib/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
--!strict

--[[
Thread Pool 1.0.0-beta
A library for creating Thread Pools to improve performance and reduce latency.
https://clownxz.github.io/ThreadPool/
]]

--[=[
@class ThreadPool
Recyles threads instead of creating a new thread everytime you want to run your code in a thread.
**Usage**
```lua
local ThreadPool = Require(path.to.module)
local myThreadPool = ThreadPool.new()
myThreadPool:spawn(function(...)
print(...) -- Prints "Hello World"
end, "Hello, world!")
```
]=]
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
@private
@tag Internal Use Only
An Internal Function for use when passing arguments into a recycled thread.
@param callback (T...) -> nil
@param ... T...
@return void
]=]
function ThreadPool:_call<T...>(callback: (T...) -> nil, ...: T...)
local index = #self._openThreads

-- Store thread and remove it from openThreads table
local thread = self._openThreads[index]
self._openThreads[index] = nil

-- Yield until callback finishes execution
callback(...)
table.insert(self._openThreads, thread) -- Store the newly opened Thread into openThreads
end

--[=[
@method _createThread
@within ThreadPool
@private
@tag Internal Use Only
Creates a new thread in the ThreadPool.
@return void
]=]
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)
coroutine.resume(newThread :: thread)

table.insert(self._openThreads, newThread)
end

--[=[
@method spawn
@within ThreadPool
Runs the provided function on a new or reused thread with the supplied parameters.
@param callback (...: any) -> nil
@param ... any
@return void
]=]
function ThreadPool:spawn<T...>(callback: (T...) -> nil, ...: T...)
if #self._openThreads < 1 then
self:_createThread()
end

coroutine.resume(self._openThreads[#self._openThreads], callback, ...)
self._openThreads[#self._openThreads] = nil
end

--[=[
@function new
@within ThreadPool
Creates a new `ThreadPool` Instance.
:::note
You can specify the amount of threads the ThreadPool will keep open by setting the `threadCount` parameter.
You can also specify the max time the Thread will be cached for by setting the `cachedThreadLifetime` parameter.
Setting this parameter to 0 will disable caching.
@param threadCount number?
@param cachedThreadLifetime number?
@return ThreadPool
]=]
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

-- Create initial new threads
for n = 1, math.abs(self._threadCount), 1 do
self:_createThread()
end

return self
end

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

return ThreadPool
23 changes: 23 additions & 0 deletions moonwave.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
title = "ThreadPool"

[docusaurus]

[[navbar.items]]
href = "https://discord.gg/gMWmuaZEY6"
label = "Discord"
position = "right"

[footer]
style = "dark"
copyright = "Copyright © 2023 Clownxz. Built with Moonwave and Docusaurus"

[[footer.links]]
title = "Links"

[[footer.links.items]]
label = "Clown's Circus Discord"
href = "https://discord.gg/gMWmuaZEY6"

[[footer.links.items]]
label = "Clownxz on Github"
href = "https://github.com/Clownxz"
1 change: 1 addition & 0 deletions selene.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std = "Roblox"
1 change: 1 addition & 0 deletions sourcemap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"ThreadPool","className":"ModuleScript","filePaths":["lib\\init.lua","default.project.json"]}

0 comments on commit 7c9806c

Please sign in to comment.