Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp queue #486

Open
3 tasks
D4isDAVID opened this issue Jun 16, 2024 · 3 comments
Open
3 tasks

Revamp queue #486

D4isDAVID opened this issue Jun 16, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@D4isDAVID
Copy link
Member

D4isDAVID commented Jun 16, 2024

The problem

  • The queue currently keeps up a thread for every player in queue, which can be bad with high player counts.
  • The points system isn't implemented, and it can lead to additional enhancements to the queue.
  • The queue lacks a grace period feature that lets players reconnect without waiting in queue shortly after disconnecting.

Ideal solution

  • The queue should use a single while-loop thread instead of keeping up a thread for every player.
  • Add points system for built-in queue #367
  • Add grace period option where players will have a configurable amount of time when they can reconnect without waiting in queue.

Alternative solutions

No response

Additional context

No response

@D4isDAVID D4isDAVID added the enhancement New feature or request label Jun 16, 2024
@D4isDAVID D4isDAVID self-assigned this Jun 16, 2024
@TransitNode
Copy link
Contributor

I might add to this that using coroutines together with a task queue could be very beneficial for a queue-system over a single while loop-thread. Since coroutines can be suspended and resumed, the queue-system can handle a large number of concurrent connections without the overhead of threads, but I must advise that multi-threading is almost always necessary for a queue system, in my opinion mixing threads with coroutines could achieve a good amount parallelism.

pseudo-code example:

-- Coroutine-based Queue System with Threads

-- Data structures
local queue = {} -- The main queue to store players
local taskQueue = {} -- Queue to hold coroutine tasks
local threadQueue = {} -- Queue to hold threads

-- Helper function to add a task to the queue
local function addTask(task)
    local co = coroutine.create(task) -- Create a new coroutine from the task function
    table.insert(taskQueue, co) -- Add the coroutine to the task queue
end

-- Helper function to add a thread to the queue
local function addThread(thread)
    table.insert(threadQueue, thread) -- Add the thread to the thread queue
end

-- Event loop for coroutines and threads
local eventLoop = coroutine.create(function()
    while true do
        local task = table.remove(taskQueue, 1) -- Get the next task from the task queue
        if task then
            local success, result = pcall(task) -- Execute the task using pcall to catch errors
            if success then
                local thread = coroutine.create(function()
                    for i = 1, #threadQueue do
                        local thread = threadQueue[i]
                        local success, err = pcall(thread) -- Execute each thread using pcall
                        if not success then
                            print("Error in thread: " .. err)
                        end
                    end
                    coroutine.yield(result) -- Yield the result of the coroutine task
                end)
                addThread(thread) -- Add the new thread to the thread queue
            else
                print("Error in thread: " .. result) -- Print the error if the task failed
            end
        else
            coroutine.yield() -- Yield control if no tasks available
        end
    end
end)

-- Dequeue function
local function dequeue()
    addTask(function()
        local threadCount = #threadQueue -- Get the number of threads in the queue
        if threadCount > 0 then
            for i = 1, threadCount do
                local thread = threadQueue[i]
                local success, result = pcall(thread) -- Execute each thread using pcall
                if success then
                    print("Thread success: " .. result) -- Print the result if the thread succeeded
                else
                    print("Thread error: " .. result) -- Print the error if the thread failed
                end
            end
        else
            print("No threads to execute") -- Print a message if there are no threads to execute
        end
    end)
end

Another suggestion is to add a player reservation system, so that users can reserve slots for important people, encase of an ingame event or such.

Instead of having a fixed set of sub-queues with predefined priorities, a new queue function could dynamically prioritize players based on various factors such as playtime or anything else the user might want configure. Give weights to each factor. Ofc keeping the fixed sub-set queue system would be a good idea, but having a configuration choice to pick which system to use is always a favourable outcome.

@D4isDAVID
Copy link
Member Author

Thanks for the suggestions.

I want to clarify that implementing the points system will be done in a way where all of that is possible with the correct configuration. It will be replacing the sub-queue system completely but it I'll do it in a way where it's possible to replicate the functionality.

@Manason
Copy link
Member

Manason commented Jun 19, 2024

Stepping back to talk about queuing at a high level, I haven't reviewed the queue code in a while. What computation does the server need to do concurrently? My suspicion is that concurrency is not needed, as even updating 10k players in the queue synchronously should take O(ms)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Todo
Development

No branches or pull requests

3 participants