Context in Lua

Here’s the translation of the Go code to Lua, with explanations in Markdown format suitable for Hugo:

In the previous example, we looked at setting up a simple HTTP server. HTTP servers are useful for demonstrating the usage of coroutines for controlling cancellation. In Lua, we can use coroutines to manage concurrent operations and handle cancellation.

local http = require("socket.http")
local ltn12 = require("ltn12")

function hello(req, res)
    print("server: hello handler started")

    -- Simulate some work
    local co = coroutine.create(function()
        local start = os.time()
        while os.time() - start < 10 do
            coroutine.yield()
        end
        res.body = "hello\n"
    end)

    while coroutine.status(co) ~= "dead" do
        local success, err = coroutine.resume(co)
        if not success then
            print("server: ", err)
            res.status = 500
            res.body = err
            break
        end
        -- Check for cancellation (simulated)
        if math.random() < 0.1 then  -- 10% chance of cancellation
            print("server: request cancelled")
            res.status = 500
            res.body = "Request cancelled"
            break
        end
    end

    print("server: hello handler ended")
end

-- Set up the server
local server = assert(socket.bind("*", 8090))
print("Server listening on port 8090")

while true do
    local client = server:accept()
    local req = {}
    local res = {headers = {}, body = ""}

    -- Read the request
    req.body = {}
    req.socket = client
    req.method, req.url, req.httpversion = client:receive():match("(%S+)%s+(%S+)%s+HTTP/(%d%.%d)")

    -- Handle the request
    hello(req, res)

    -- Send the response
    local response = string.format("HTTP/1.1 %d OK\r\n", res.status or 200)
    for k, v in pairs(res.headers) do
        response = response .. string.format("%s: %s\r\n", k, v)
    end
    response = response .. "\r\n" .. (res.body or "")
    client:send(response)
    client:close()
end

In this Lua version, we’ve simulated the concept of context and cancellation using coroutines. The hello function creates a coroutine that runs for up to 10 seconds. We periodically check if the coroutine has completed or if a cancellation has occurred (simulated with a random chance).

To run the server:

$ lua server.lua &

To simulate a client request to /hello, you can use a tool like curl. However, since we’re simulating cancellation randomly in the server, you might need to try multiple times to see a cancellation:

$ curl localhost:8090/hello

You might see output like:

server: hello handler started
server: request cancelled
server: hello handler ended

Or if the request completes successfully:

server: hello handler started
server: hello handler ended
hello

This example demonstrates how you can use coroutines in Lua to manage long-running operations and handle cancellation, similar to how Go uses contexts for the same purpose.