mirror of
https://github.com/lune-org/docs.git
synced 2024-12-12 21:10:36 +00:00
140 lines
3 KiB
Text
140 lines
3 KiB
Text
|
# The Task Scheduler
|
||
|
|
||
|
Lune has a built-in task scheduler, which can let you run things at fixed intervals, ensure some
|
||
|
work happens after everything else is already done, and more.
|
||
|
|
||
|
## Spawning Tasks & Waiting
|
||
|
|
||
|
This example script will run several tasks concurrently, in lightweight Lua threads, also known as
|
||
|
coroutines:
|
||
|
|
||
|
```lua copy
|
||
|
local task = require("@lune/task")
|
||
|
|
||
|
print("Hello, scheduler!")
|
||
|
|
||
|
task.spawn(function()
|
||
|
print("Spawned a task that will run instantly but not block")
|
||
|
task.wait(2)
|
||
|
print("The instant task resumed again after 2 seconds")
|
||
|
end)
|
||
|
|
||
|
print("Spawning a delayed task that will run after 5 seconds")
|
||
|
|
||
|
task.delay(5, function()
|
||
|
print("Waking up from my deep slumber...")
|
||
|
task.wait(1)
|
||
|
print("Hello again!")
|
||
|
task.wait(1)
|
||
|
print("Goodbye again! 🌙")
|
||
|
end)
|
||
|
```
|
||
|
|
||
|
## Deferring Work
|
||
|
|
||
|
This example script runs a bit of work after all other threads have finished their work or are
|
||
|
yielding waiting for some other result:
|
||
|
|
||
|
```lua copy
|
||
|
local task = require("@lune/task")
|
||
|
|
||
|
task.defer(function()
|
||
|
print("All the scheduled work has finished, let's do some more!")
|
||
|
local a = 0
|
||
|
for _ = 1, 100000 do
|
||
|
local b = a + 1
|
||
|
end
|
||
|
print("Phew, that was tough.")
|
||
|
end)
|
||
|
|
||
|
print("Working...")
|
||
|
local s = ""
|
||
|
for _ = 1, 5000 do
|
||
|
s ..= ""
|
||
|
end
|
||
|
print("Done!")
|
||
|
```
|
||
|
|
||
|
## Advanced Usage & Async
|
||
|
|
||
|
Spawning tasks like this can be very useful together with asynchronous APIs from other built-in
|
||
|
libraries, such as [`net.request`](../../api-reference/net.md#request):
|
||
|
|
||
|
```lua copy
|
||
|
local net = require("@lune/net")
|
||
|
local task = require("@lune/task")
|
||
|
|
||
|
local completed = false
|
||
|
task.spawn(function()
|
||
|
while not completed do
|
||
|
print("Waiting for response...")
|
||
|
task.wait() -- Wait the minimum amount possible
|
||
|
end
|
||
|
print("No longer waiting!")
|
||
|
end)
|
||
|
|
||
|
print("Sending request")
|
||
|
net.request("https://google.com")
|
||
|
print("Got response")
|
||
|
|
||
|
completed = true
|
||
|
```
|
||
|
|
||
|
<details>
|
||
|
<summary>Bonus</summary>
|
||
|
|
||
|
## Barebones Signal Implementation
|
||
|
|
||
|
Using the task library, it becomes trivial to implement signal objects that take callbacks to run
|
||
|
when a signal is fired, and that can handle both synchronous and yielding (async) callbacks without
|
||
|
additional complexity:
|
||
|
|
||
|
```lua copy
|
||
|
local task = require("@lune/task")
|
||
|
|
||
|
local function newSignal()
|
||
|
local callbacks = {}
|
||
|
|
||
|
local function connect(callback: (...any) -> ())
|
||
|
table.insert(callbacks, callback)
|
||
|
end
|
||
|
|
||
|
local function fire(...: any)
|
||
|
for _, callback in callbacks do
|
||
|
task.spawn(callback, ...)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return connect, fire
|
||
|
end
|
||
|
|
||
|
local connectToThing, fireThing = newSignal()
|
||
|
|
||
|
connectToThing(function(value)
|
||
|
print("Callback #1 got value:", value)
|
||
|
task.wait(1)
|
||
|
print("Callback #1 still has value:", value)
|
||
|
end)
|
||
|
|
||
|
connectToThing(function(value)
|
||
|
print("Callback #2 got value:", value)
|
||
|
task.wait(0.5)
|
||
|
print("Callback #2 still has value:", value)
|
||
|
end)
|
||
|
|
||
|
print("Before firing")
|
||
|
fireThing(123)
|
||
|
print("After firing")
|
||
|
|
||
|
--> Before firing
|
||
|
--> Callback #1 got value: 123
|
||
|
--> Callback #2 got value: 123
|
||
|
--> After firing
|
||
|
--> ...
|
||
|
--> Callback #2 still has value: 123
|
||
|
--> ...
|
||
|
--> Callback #1 still has value: 123
|
||
|
```
|
||
|
|
||
|
</details>
|