Skip to content

Scheck Concurrency Strategy


  • Version: 1.0.7-7-g251eead
  • Release Date: 2023-04-06 11:17:57
  • Supported OS: windows/amd64, windows/386, linux/arm, linux/arm64, linux/386, linux/amd64

Using Thread Pool and Task Queue to Schedule Lua Scripts

The original approach was to have one lua proto corresponding to one lua.state object, with each state object loading common lib libraries and shared data. Each lua proto had a dedicated timer at runtime, which caused many lua scripts to run in bursts simultaneously, and all the states consumed too much memory. Therefore, the following optimizations were made:

  • Create a lua.state pool, take one from the pool when needed, and return it after use.
  • Make the thread pool size dynamic so that when multiple tasks need to run concurrently, enough state objects are available for invocation.
  • Remove all timers and change them to run at intervals. The reason is that the lua scripts executed by Scheck do not require high real-time performance, and some runtime variation is acceptable.

Thread Pool

A lua.state is the smallest unit for running a lua proto, also known as a lua virtual machine. The thread pool is composed of multiple lua.state objects.

  • When a state object is requested from the pool, if the pool still has available objects, one is taken from the pool.
  • If the pool is empty but the number of running states has not yet reached the maximum allowed capacity (cap), a new state object is created. This state object is recycled when the invocation ends.
  • After a state object from the pool is used, it is returned immediately.
  • There is an initial size and a maximum capacity, allowing peaks in the number of running states.

Task Queue

  • Convert all lua run times into a queue composed of intervals.
  • Traverse the task queue and pick the task whose scheduled time is closest to the current time. If the scheduled time has already passed, run it immediately.
  • If there is still time before the scheduled time, start a timer and run the task when the timer fires.
  • When a task runs, it needs a state to execute the lua proto, so it must acquire a state from the thread pool. If the pool is empty and the total number of running states has reached the configured peak, the task will enter a waiting state until another task finishes and returns the state.

Feedback

Is this page helpful?