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.