An execution queue is a queue of closures, which are queued up to be run in sequence by the engine. Unlike set_timeout and set_interval, there is no time component, it's simply a queue of operations to execute sequentially. There can be multiple execution queues as well, though there is a single default queue. The general idea is that queueing up a closure is instant. All the queue operations return immediately, and the closure is run at a later time. Delays and queue management functions are all provided to make doing complex operations possible.
Basic Queue Usage
The most basic operation is the
queue_push() function. This pushes a new routine at the end of the queue. For instance:
would be valid. This will run the code
msg('Hello World!') at the next available opportunity, after other queued operations occur. Each
time the queue runs an operation, it frees the server thread back up, so this is a useful mechanism for scheduling extremely long running tasks, without
killing the server. Any value returned from the closure is ignored however, so it is not useful for things that need to block. Note that between operation executions, there will likely be around a 10ms delay, while control of the main thread is re-gained, and a 50ms delay between noticeable ticks. This makes
the system undesirable for fluid animations, however, this is not a limitation of MethodScript itself.
There can be multiple queues. Each queue is simply named something, with the default queue being "default". Operations across queues are not executed in any particular order with respect to each other, but within each queue, operations are guaranteed to be sequential. Each queue function takes an optional parameter which specifies the queue name.
queue_push(closure(msg('Hello World!')), 'default')
To make a new queue, just use a new name, it will be created automatically.
Delays can be inserted into a queue as well. This delay will suspend the queue's operation momentarily, but will not freeze the server, since the delay will be on the execution queue's thread, not the server thread. This is a seperate operation, and uses the
queue_delay(1000, 'default') #Put a 1 second delay on the default queue. 'default' is optional.
Other Queue Operations
The queue works like a doubly ended queue. There are other operations to control this queue, with a few caveats. Once an operation has been submitted for execution, it cannot be cancelled anymore, and operations are always pulled from the front of the queue. You can use these other methods to control the queue:
||Removes the last operation on the queue.|
||Removes the operation on the queue that would be running next|
||Instead of pushing an operation onto the back of the queue, pushes it to the front. Barring other calls to queue_push_front, that means that this operation will execute next.|
||Clears all pending operations from the queue|
||Returns true if a queue is currently running|
||Works like queue_delay(), but pushes the delay on the front of the queue|
This example splits a loop up into many smaller chunks, which should cause the server to not freeze
for(assign(@i, -5000), @i < 5000, @i++, queue_push(closure(set_block_at(@i, 50, @i, 1, 'world')), 'block-set') #Sets a diagonal line of blocks to stone, from [-5000, 50, -5000] to [5000, 50, 5000] )
Queing up the operations should complete relatively fast, but the full task will take a while.