Tuesday, 18 March 2014

Asynchronous download using Coroutine - Lua

require("socket")

function download()
    local host, file, port = "www.w3.org", "/TR/REC-html32.html", 80
    local connection = assert(socket.connect(host, port))
    local count = 0    -- counts number of bytes read

    connection:send("GET " .. file .. " HTTP/1.0\r\n\r\n")

    while true do
        local response, status = receive(connection)

        if(response ~= nill) then count = count + string.len(response) end
        --print(response)
        if status == "closed" then break end
    end

    connection:close()

    print(file, count)
end

--[[function receive(connection)
    connection:settimeout(0)
    return connection:receive(2^10)
end]]--

function receive(connection)
    connection:settimeout(0)   -- do not block

    local response, status = connection:receive(2^10)

    if status == "timeout" then
        coroutine.yield(connection)
    end

    return response, status
end

threads = {}    -- list of all live threads

function get ()
  -- create coroutine
  local co = coroutine.create(function ()    download()  end)
  -- insert it in the list
  table.insert(threads, co)
end

function dispatcher()
    while true do
        local count = table.getn(threads)

        if(count <= 0) then break end

        for i = 1, count do
            local status, ret = coroutine.resume(threads[i])

            if not ret then table.remove(threads, i) break end
        end
    end
end

get()
get()
get()
get()
get()

dispatcher()

No comments: