I just started experimenting with socket.http for my plugin and started noticing that while the code was running (e.g retrieving version information from a website), you can't do anything in mushclient before the code finishes. Is it possible to have the code not cause the freezing?
socket.http freezing mushclient
Posted by Victorious on Sat 21 Dec 2013 03:45 AM — 6 posts, 23,122 views.
I think you can do non-blocking calls, but I can't remember how. Browse the documentation for the Lua socket library, it may have examples.
I've been looking into using threads to try solving this problem and based on section 9.4 of the programming in lua manual, I've came up with the following code. I'm still trying to grasp the concepts but so far, this increases download speeds but mushclient is still unresponsive during this process because the dispatcher() has control.
[EDIT] Code tags added.
threads = {} -- list of all live threads
function get (host, file, output)
-- create coroutine
local co = coroutine.create(function ()
download(host, file, output)
end)
-- insert it in the list
table.insert(threads, co)
end
function dispatcher ()
while true do
local n = table.getn(threads)
if n == 0 then break end -- no more threads to run
local connections = {}
for i=1,n do
local status, res = coroutine.resume(threads[i])
if res == nil then -- thread finished its task
table.remove(threads, i)
break
else -- timeout
table.insert(connections, res)
end
end
if table.getn(connections) == n then
socket.select(connections)
end
end
end
function receive (connection)
connection:settimeout(0.051) -- do not block
local s, status = connection:receive(2^10)
if status == "timeout" then
coroutine.yield(connection)
end
return s, status
end
function download (host, file, output)
f = io.output(output)
local c = assert(socket.connect(host, 80))
local count = 0 -- counts number of bytes read
c:send("GET " .. file .. " HTTP/1.0\r\n\r\n")
while true do
s, status = receive(c)
if s ~= nil then
count = count + string.len(s)
--assembles the actual file
if actualfile == nil then
actualfile = s
else
actualfile = actualfile..s
end
end
if status == "closed" then break end
end
c:close()
print(file, count) --filename and length
f:write(actualfile)
f:flush()
f:close()
end
[EDIT] Code tags added.
I think the problem with trying to make something non-blocking is that you would then have to periodically check if the I/O was completed. I'm not sure how you would do that, maybe with a timer.
Hmmm, maybe something like lua lanes might work but was having trouble compiling the dll and getting it integrated with mushclient.
I think you will find there are problems with this sort of thing because MUSHclient has a "main loop" and non-blocking code tends to want to have its own "main loop".