Skip to main content

PromiseQueue

This item is only intended to be used by the module's authors. Private

Implements a queue that processes asynchronous operations (represented by functions returning Promises or synchronous functions) one at a time, ensuring serial execution.

Purpose: Useful for scenarios where operations on a shared resource must not run concurrently to prevent race conditions or ensure logical order. For example, processing updates to a specific player's data session.

Core Logic:

  • Operations are added to the queue via the add method.
  • Each operation is wrapped in a Promise.
  • A single processing loop (PromiseQueue:_processQueue) runs as long as the queue is not empty.
  • The loop takes the next item, executes its associated function, and waits for its Promise to resolve or reject before moving to the next item.
  • Includes timeout and deadlock detection for individual items.
  • Supports adding an operation atomically across multiple queues (PromiseQueue:multiQueueAdd).

Types

CreatePromiseQueueParams

interface CreatePromiseQueueParams {
loggerLog.Logger
}

Parameters for creating a new PromiseQueue instance.

Functions

new

PromiseQueue.new(
paramsCreatePromiseQueueParams--

Configuration parameters.

) → PromiseQueue--

A new PromiseQueue object.

Creates a new PromiseQueue instance.

multiQueueAdd

PromiseQueue.multiQueueAdd(
queues{PromiseQueue},--

A table array of PromiseQueue instances to coordinate.

callback() → ()--

The function to execute once all queues are ready.

) → Promise--

A Promise that resolves/rejects with the result/error of the callback.

Atomically adds a callback function to be executed across multiple queues.

Ensures that the callback only runs when it has effectively acquired the "lock" (become the currently processing item) on all specified queues simultaneously. This is useful for operations that need to coordinate across multiple resources managed by separate queues.

Mechanism:

  1. Uses _addResumableBlock to add a blocking item to each queue.
  2. Waits for all these blocking items to become active (i.e., all _addResumableBlock promises resolve, returning their resume functions).
  3. Once all queues are blocked, executes the provided callback.
  4. After the callback finishes (successfully or with an error), calls all the resume functions to unblock all the queues.

add

PromiseQueue:add(
callback() → T--

The function to execute. This function can be synchronous or return a Promise. Its result or error will resolve/reject the Promise returned by this add call.

) → Promise<T>--

A Promise that resolves or rejects with the result or error of the provided callback function once it's processed by the queue.

Adds a new operation (callback function) to the end of the queue.

The callback will be executed only after all preceding items in the queue have completed.

Show raw api
{
    "functions": [
        {
            "name": "new",
            "desc": "Creates a new PromiseQueue instance.",
            "params": [
                {
                    "name": "params",
                    "desc": "Configuration parameters.",
                    "lua_type": "CreatePromiseQueueParams"
                }
            ],
            "returns": [
                {
                    "desc": "A new PromiseQueue object.",
                    "lua_type": "PromiseQueue"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 104,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "add",
            "desc": "Adds a new operation (callback function) to the end of the queue.\n\nThe callback will be executed only after all preceding items in the queue\nhave completed.",
            "params": [
                {
                    "name": "callback",
                    "desc": "The function to execute. This function can be synchronous or return a Promise. Its result or error will resolve/reject the Promise returned by this `add` call.",
                    "lua_type": "() -> T"
                }
            ],
            "returns": [
                {
                    "desc": "A Promise that resolves or rejects with the result or error of the provided `callback` function once it's processed by the queue.",
                    "lua_type": "Promise<T>"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 122,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "_processQueue",
            "desc": "Internal function that processes items from the queue sequentially.\nIt runs as long as there are items in the queue.",
            "params": [],
            "returns": [],
            "function_type": "method",
            "private": true,
            "source": {
                "line": 164,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "addResumableBlock",
            "desc": "Internal helper function used by `multiQueueAdd`.\nAdds a special \"blocking\" item to a single queue. This item's function\nreturns a Promise that only resolves when an external `resume` function is called.\n`resume` is just a Promise resolver function - calling it unblocks the queue item.",
            "params": [
                {
                    "name": "queue",
                    "desc": "The PromiseQueue instance to add the block to.",
                    "lua_type": "PromiseQueue"
                }
            ],
            "returns": [
                {
                    "desc": "A Promise that resolves with the `resume` function once the block becomes the active item in the queue.",
                    "lua_type": "Promise<() -> ()>"
                }
            ],
            "function_type": "static",
            "private": true,
            "source": {
                "line": 232,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "multiQueueAdd",
            "desc": "Atomically adds a callback function to be executed across multiple queues.\n\nEnsures that the callback only runs when it has effectively acquired the \"lock\"\n(become the currently processing item) on *all* specified queues simultaneously.\nThis is useful for operations that need to coordinate across multiple resources\nmanaged by separate queues.\n\n**Mechanism:**\n1. Uses `_addResumableBlock` to add a blocking item to each queue.\n2. Waits for all these blocking items to become active (i.e., all `_addResumableBlock`\n   promises resolve, returning their `resume` functions).\n3. Once all queues are blocked, executes the provided `callback`.\n4. After the `callback` finishes (successfully or with an error), calls all the\n   `resume` functions to unblock all the queues.",
            "params": [
                {
                    "name": "queues",
                    "desc": "A table array of PromiseQueue instances to coordinate.",
                    "lua_type": "{ PromiseQueue }"
                },
                {
                    "name": "callback",
                    "desc": "The function to execute once all queues are ready.",
                    "lua_type": "() -> ()"
                }
            ],
            "returns": [
                {
                    "desc": "A Promise that resolves/rejects with the result/error of the `callback`.",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 267,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "_getLogContext",
            "desc": "Internal helper to generate a context table for logging.",
            "params": [
                {
                    "name": "item",
                    "desc": "(Optional) The QueueItem currently being processed.",
                    "lua_type": "QueueItem?"
                }
            ],
            "returns": [
                {
                    "desc": "A table containing common context fields like queue length and item ID.",
                    "lua_type": "{ [string]: any }"
                }
            ],
            "function_type": "method",
            "private": true,
            "source": {
                "line": 297,
                "path": "src/PromiseQueue.luau"
            }
        }
    ],
    "properties": [],
    "types": [
        {
            "name": "PromiseQueueImpl",
            "desc": "Internal implementation details and methods for the PromiseQueue class.",
            "fields": [
                {
                    "name": "__index",
                    "lua_type": "PromiseQueueImpl",
                    "desc": ""
                },
                {
                    "name": "new",
                    "lua_type": "(params: CreatePromiseQueueParams) -> PromiseQueue",
                    "desc": ""
                },
                {
                    "name": "_processQueue",
                    "lua_type": "(self: PromiseQueue) -> ()",
                    "desc": ""
                },
                {
                    "name": "_addResumableBlock",
                    "lua_type": "(queue: PromiseQueue) -> Promise<() -> ()>",
                    "desc": ""
                },
                {
                    "name": "_getLogContext",
                    "lua_type": "(self: PromiseQueue, item: QueueItem?) -> { [string]: any }",
                    "desc": ""
                },
                {
                    "name": "add",
                    "lua_type": "(self: PromiseQueue, callback: () -> ()) -> Promise",
                    "desc": ""
                },
                {
                    "name": "multiQueueAdd",
                    "lua_type": "(queues: { PromiseQueue }, callback: () -> ()) -> Promise",
                    "desc": "Public static method"
                }
            ],
            "private": true,
            "source": {
                "line": 39,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "PromiseQueueProps",
            "desc": "Internal properties stored within a PromiseQueue instance.",
            "fields": [
                {
                    "name": "_queue",
                    "lua_type": "{ QueueItem }",
                    "desc": "The actual queue holding items to be processed."
                },
                {
                    "name": "_logger",
                    "lua_type": "Log.Logger",
                    "desc": "Logger instance for internal logging."
                },
                {
                    "name": "_totalItemCount",
                    "lua_type": "number",
                    "desc": "Counter for assigning unique IDs to queue items."
                }
            ],
            "private": true,
            "source": {
                "line": 58,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "QueueItem",
            "desc": "Represents a single item within the queue.",
            "fields": [
                {
                    "name": "id",
                    "lua_type": "number",
                    "desc": "Unique identifier for the item within this queue instance."
                },
                {
                    "name": "fn",
                    "lua_type": "() -> ()",
                    "desc": "The function to execute for this item. Can be sync or return a Promise."
                },
                {
                    "name": "resolve",
                    "lua_type": "(value: any) -> ()",
                    "desc": "The resolve function of the Promise returned by `add`."
                },
                {
                    "name": "reject",
                    "lua_type": "(error: any) -> ()",
                    "desc": "The reject function of the Promise returned by `add`."
                },
                {
                    "name": "trace",
                    "lua_type": "string",
                    "desc": "Debug traceback captured when the item was added."
                }
            ],
            "private": true,
            "source": {
                "line": 75,
                "path": "src/PromiseQueue.luau"
            }
        },
        {
            "name": "CreatePromiseQueueParams",
            "desc": "Parameters for creating a new PromiseQueue instance.",
            "fields": [
                {
                    "name": "logger",
                    "lua_type": "Log.Logger",
                    "desc": ""
                }
            ],
            "source": {
                "line": 94,
                "path": "src/PromiseQueue.luau"
            }
        }
    ],
    "name": "PromiseQueue",
    "desc": "Implements a queue that processes asynchronous operations (represented by functions\nreturning Promises or synchronous functions) one at a time, ensuring serial execution.\n\n**Purpose:** Useful for scenarios where operations on a shared resource must not\nrun concurrently to prevent race conditions or ensure logical order. For example,\nprocessing updates to a specific player's data session.\n\n**Core Logic:**\n- Operations are added to the queue via the `add` method.\n- Each operation is wrapped in a `Promise`.\n- A single processing loop ([PromiseQueue:_processQueue]) runs as long as the queue is not empty.\n- The loop takes the next item, executes its associated function, and waits for\n  its Promise to resolve or reject before moving to the next item.\n- Includes timeout and deadlock detection for individual items.\n- Supports adding an operation atomically across multiple queues ([PromiseQueue:multiQueueAdd]).",
    "private": true,
    "source": {
        "line": 21,
        "path": "src/PromiseQueue.luau"
    }
}