Non Blocking Channel Operations in Lua
Our first example demonstrates non-blocking channel operations in Lua. While Lua doesn’t have built-in channels or select statements like some other languages, we can simulate similar behavior using coroutines and a custom implementation.
local function make_channel()
local channel = {}
local queue = {}
local waiters = {}
function channel.send(value)
if #waiters > 0 then
coroutine.resume(table.remove(waiters, 1), value)
else
table.insert(queue, value)
end
end
function channel.receive()
if #queue > 0 then
return table.remove(queue, 1)
else
table.insert(waiters, coroutine.running())
return coroutine.yield()
end
end
return channel
end
local messages = make_channel()
local signals = make_channel()
-- Here's a non-blocking receive. If a value is
-- available on `messages` then it will be returned,
-- otherwise it will return nil immediately.
local function non_blocking_receive(channel)
local co = coroutine.create(function()
return channel.receive()
end)
local success, result = coroutine.resume(co)
if coroutine.status(co) == "suspended" then
channel.send(nil) -- Cancel the receive
return nil
else
return result
end
end
-- Attempt a non-blocking receive
local msg = non_blocking_receive(messages)
if msg then
print("received message", msg)
else
print("no message received")
end
-- A non-blocking send works similarly. Here `msg`
-- is sent to the `messages` channel if possible,
-- otherwise it returns false.
local function non_blocking_send(channel, value)
local sent = false
local co = coroutine.create(function()
channel.send(value)
sent = true
end)
coroutine.resume(co)
return sent
end
msg = "hi"
if non_blocking_send(messages, msg) then
print("sent message", msg)
else
print("no message sent")
end
-- We can implement a multi-way non-blocking
-- select by checking multiple channels.
local function multi_select()
local msg = non_blocking_receive(messages)
if msg then
print("received message", msg)
return
end
local sig = non_blocking_receive(signals)
if sig then
print("received signal", sig)
return
end
print("no activity")
end
multi_select()
When you run this Lua script, it will output:
no message received
no message sent
no activity
This example demonstrates how to implement non-blocking operations on channels in Lua. While Lua doesn’t have built-in support for these concepts, we can create similar functionality using coroutines and custom channel implementations.
The make_channel
function creates a channel-like object with send
and receive
methods. The non_blocking_receive
and non_blocking_send
functions use coroutines to implement non-blocking operations on these channels.
The multi_select
function simulates a multi-way non-blocking select by checking multiple channels in sequence.
While this implementation differs from the original in terms of syntax and underlying mechanisms, it achieves similar functionality in terms of non-blocking channel operations.