Module eco
Core runtime for lua-eco.
This module implements the built-in event loop and cooperative coroutine scheduler (epoll + timers). Most I/O in lua-eco is exposed as synchronous looking Lua APIs, but is implemented using non-blocking file descriptors. When an operation would block, the running coroutine yields and is resumed automatically when the descriptor becomes ready.
Exported constants:
VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH: semantic version parts.VERSION: full version string.READ,WRITE: event flags for use with io:wait.
This module is built into the eco interpreter and is loaded
automatically into _G.eco. The interpreter also schedules user
scripts by creating a coroutine via eco.run(...) and starts the
scheduler with eco.loop() automatically.
Usage:
#!/usr/bin/env eco
local time = require 'eco.time'
-- eco is injected into _G by the eco interpreter.
eco.run(function(name)
local co = coroutine.running()
while true do
print(time.now(), name, co)
time.sleep(1.0)
end
end, 'eco1')
eco.run(function(name)
local co = coroutine.running()
while true do
print(time.now(), name, co)
time.sleep(2.0)
end
end, 'eco2')
Functions
| io (fd) | Create a new async I/O object wrapping a file descriptor. |
| reader (fd[, read[, ctx]]) | Create a new reader object. |
| writer (fd[, write[, ctx]]) | Create a new writer object. |
| sleep (delay) | Suspend the current coroutine for a given delay. |
| run (func, ...) | Run a Lua function in a new coroutine. |
| count () | Get the number of currently tracked coroutines. |
| all () | Get a table of all currently tracked coroutines. |
| set_panic_hook ([func]) | Set or clear the scheduler panic hook. |
| set_watchdog_timeout (ms) | Set or clear coroutine resume watchdog timeout in milliseconds. |
| loop () | Run the event loop of the eco scheduler. |
| unloop () | Stop the eco scheduler main loop. |
Class io
| io:wait (ev[, timeout]) | Wait for the underlying file descriptor to become ready. |
| io:cancel () | Cancel a pending wait on this I/O object. |
Class reader
| reader:wait ([timeout]) | Wait for the underlying file descriptor to become readable. |
| reader:read (format[, timeout]) | Reads data from the underlying file descriptor in the given format. |
| reader:readfull (size[, timeout]) | Reads exactly size bytes from the underlying file descriptor. |
| reader:readuntil (needle[, timeout]) | Read until the specified needle is found. |
| reader:cancel () | Cancel a pending read operation. |
Class writer
| writer:wait ([timeout]) | Wait for the underlying file descriptor to become writable. |
| writer:write (data[, timeout]) | Write data to the writer's file descriptor. |
| writer:sendfile (path, offset, len[, timeout]) | Send a file's content to the writer's file descriptor. |
| writer:cancel () | Cancel a pending write operation. |
Functions
- io (fd)
-
Create a new async I/O object wrapping a file descriptor.
This function sets the given file descriptor to non-blocking mode and wraps it in an eco.io userdata object, allowing async I/O operations via
io:wait()andio:cancel().Parameters:
- fd int File descriptor to wrap.
Returns:
-
io
The new I/O object on success.
Or
- nil On failure.
- string Error message.
Usage:
local io = eco.io(fd) local ok, err = io:wait(eco.READ, 5) if not ok then print('I/O wait failed:', err) end
- reader (fd[, read[, ctx]])
-
Create a new reader object.
Wraps a file descriptor in an eco.reader object for async I/O. Optionally, a custom read function and context pointer can be provided.
Parameters:
- fd int File descriptor to wrap
- read lightuserdata Custom read function (optional)
- ctx lightuserdata Context pointer for the read function (optional)
Returns:
-
reader
The reader object
Or
- nil On failure
- string Error message
Usage:
local rd = eco.reader(fd) local line, err = rd:read('l') if not line then print('read fail:', err) return end print(line)
- writer (fd[, write[, ctx]])
-
Create a new writer object.
Wraps a file descriptor in an eco.writer object for asynchronous write operations. Optionally, a custom write function and context pointer can be provided.
Parameters:
- fd int File descriptor to wrap
- write lightuserdata Custom write function (optional)
- ctx lightuserdata Context pointer for the write function (optional)
Returns:
-
writer
The writer object
Or
- nil On failure
- string Error message
Usage:
local wr = eco.writer(fd) wr:write('hello world')
- sleep (delay)
-
Suspend the current coroutine for a given delay.
This function yields the current Lua coroutine and resumes it after
delayseconds.Parameters:
- delay number Number of seconds to sleep.
Usage:
print('Sleeping for 1 second...') eco.run(function() eco.sleep(1) print('Awake!') end)
- run (func, ...)
-
Run a Lua function in a new coroutine.
This function creates a new Lua coroutine, moves the provided function and its arguments into it, and resumes the coroutine immediately. The coroutine is tracked internally by eco.
Parameters:
- func function Function to run in the new coroutine.
- ... Arguments to pass to the function.
Returns:
-
thread
The newly created coroutine.
Usage:
eco.run(function(a, b) print('Running in coroutine:v', a, b) eco.sleep(1) print('Done') end, 10, 20)
- count ()
-
Get the number of currently tracked coroutines.
Returns:
-
int
Number of coroutines currently managed by eco.
Usage:
print('Active coroutines:', eco.count())
- all ()
-
Get a table of all currently tracked coroutines.
Returns:
-
table
Table of Lua coroutine objects.
Usage:
for i, co in ipairs(eco.all()) do print('Coroutine', i, co) end
- set_panic_hook ([func])
-
Set or clear the scheduler panic hook.
The hook is called when an uncaught error occurs inside a coroutine managed by eco.
The callback receives two traceback strings:
- traceback from the currently running coroutine (the one that failed)
- traceback from the coroutine/context that resumed it
Pass
nilto clear a previously installed hook.Parameters:
- func
function
Panic callback
func(traceback1, traceback2). (optional)
Usage:
eco.set_panic_hook(function(traceback1, traceback2) print(traceback1) print(traceback2) end) -- clear hook eco.set_panic_hook(nil)
- set_watchdog_timeout (ms)
-
Set or clear coroutine resume watchdog timeout in milliseconds.
If a single
resumeruns longer than this timeout, eco triggers panic and prints traceback via the existing panic path.Pass
0to disable timeout checks.Parameters:
- ms
int
Timeout in milliseconds,
0means disabled.
- ms
int
Timeout in milliseconds,
- loop ()
-
Run the event loop of the eco scheduler.
This function drives the scheduler, processing timers, I/O events, and resuming coroutines as needed.
eco.loop()returns wheneco.unloop()is called, when interrupted by SIGINT, or when there are no monitorable events left (no pending I/O watchers and no scheduled timers).Returns:
-
nil
If the loop exits normally
Or
-
string
Error message.
- unloop ()
- Stop the eco scheduler main loop.
Class io
- io:wait (ev[, timeout])
-
Wait for the underlying file descriptor to become ready.
Suspends the current coroutine until the file descriptor is ready for reading (EPOLLIN) or writing (EPOLLOUT), or until an optional timeout.
Parameters:
- ev
int
Event mask:
eco.READ,eco.WRITE, or a combination. - timeout number Timeout in seconds (default nil = no timeout). (optional)
Returns:
-
boolean
true If the underlying file descriptor to become ready.
Or
- nil On error.
- string Error message.
- ev
int
Event mask:
- io:cancel ()
-
Cancel a pending wait on this I/O object.
If a coroutine is currently suspended in
io:wait(), it will be resumed immediately andio:wait()will return nil, "canceled".Returns:
-
nil
Usage:
local io = eco.io(fd) eco.run(function() local ok, err = io:wait(eco.READ) if not ok then print('Wait failed or canceled:', err) end end) io:cancel()
Class reader
- reader:wait ([timeout])
-
Wait for the underlying file descriptor to become readable.
Parameters:
- timeout number Timeout in seconds (default nil = no timeout). (optional)
Returns:
-
boolean
true If the underlying file descriptor to become readable.
Or
- nil On error.
- string Error message.
- reader:read (format[, timeout])
-
Reads data from the underlying file descriptor in the given format.
The available formats are:
"a": reads the whole file or reads from socket until the connection closed."l": reads the next line skipping the end of line(The line is terminated by a Line Feed (LF) character (ASCII 10), optionally preceded by a Carriage Return (CR) character (ASCII 13). The CR and LF characters are not included in the returned line)."L": reads the next line keeping the end-of-line character.int: reads a string with up to this number of bytes.
Parameters:
- format int or string
- timeout number Timeout in seconds (default nil = no timeout) (optional)
Returns:
-
string
Data read from the file descriptor
Or
- nil On error or EOF
- string Error message or "eof"
Usage:
local data, err = reader:read(1024, 5) if not data then print("Read failed:", err) end
- reader:readfull (size[, timeout])
-
Reads exactly
sizebytes from the underlying file descriptor.This method will not return until it reads exactly this size of data or an error occurs.
Parameters:
- size int
- timeout number Timeout in seconds (default nil = no timeout) (optional)
Returns:
-
string
Data read from the file descriptor
Or
- nil On error or EOF
- string Error message or "eof"
- reader:readuntil (needle[, timeout])
-
Read until the specified
needleis found.This function can be called multiple times. It returns data as it arrives. When
needleis seen, it returns the data preceding it and a booleantrue. Theneedleitself is consumed and not included in returned data.Parameters:
- needle string Non-empty delimiter.
- timeout number Timeout in seconds (default nil = no timeout) (optional)
Returns:
- string Data read from the file descriptor
- boolean true when delimiter is found.
Or
- nil On error or EOF
- string Error message or "eof"
- reader:cancel ()
-
Cancel a pending read operation.
If a coroutine is currently suspended in read,
read2bor wait, it will be resumed immediately and return nil with error "canceled".Returns:
-
nil
Class writer
- writer:wait ([timeout])
-
Wait for the underlying file descriptor to become writable.
Parameters:
- timeout number Timeout in seconds (default nil = no timeout). (optional)
Returns:
-
boolean
true If the underlying file descriptor to become writable.
Or
- nil On error.
- string Error message.
- writer:write (data[, timeout])
-
Write data to the writer's file descriptor.
Writes the given string
datato the file descriptor wrapped by this eco.writer. If the write would block, the coroutine is suspended and resumed automatically when the descriptor is writable.Parameters:
- data string Data to write
- timeout number Timeout in seconds (default nil = no timeout) (optional)
Returns:
-
int
Number of bytes written
Or
- nil On error
- string Error message
- writer:sendfile (path, offset, len[, timeout])
-
Send a file's content to the writer's file descriptor.
Uses the sendfile system call to send
lenbytes starting fromoffsetof the file atpathto the writer's file descriptor. If the operation would block, the coroutine is suspended and resumed automatically when the descriptor is writable.Parameters:
- path string Path to the file
- offset int Offset in the file to start sending
- len int Number of bytes to send
- timeout number Timeout in seconds (default nil = no timeout) (optional)
Returns:
-
int
Number of bytes sent
Or
- nil On error
- string Error message
Usage:
local wr = eco.writer(fd) local n, err = wr:sendfile('/tmp/file.txt', 0, 1024) if not n then print('Sendfile failed:', err) end
- writer:cancel ()
-
Cancel a pending write operation.
If a coroutine is currently suspended in write, sendfile or wait, it will be resumed immediately and return nil with error "canceled".
Returns:
-
nil