Skip to content

Instantly share code, notes, and snippets.

@mwild1
Created July 1, 2011 11:28
Show Gist options
  • Save mwild1/1058346 to your computer and use it in GitHub Desktop.
Save mwild1/1058346 to your computer and use it in GitHub Desktop.
local wrapclient = require "net.server".wrapclient;
local socket = require "socket";
local coroutine = coroutine;
local comap = {};
local function yield(conn)
comap[conn] = coroutine.running();
local r = coroutine.yield();
comap[conn] = nil;
return r;
end
local function wrap_blocking_socket(conn, err)
if not conn then return nil, err; end
local coro = assert(coroutine.running(), "Can only wrap blocking socket inside a coroutine");
conn:settimeout(0);
local listener = { default_mode = "*l" };
function listener.onincoming(conn, data)
coroutine.resume(coro, data);
end
local connect_host, connect_port = conn:getpeername();
return wrapclient(conn, connect_host, connect_port, listener, listener.default_mode);
end
local function async_wrap(f, ...)
local f_ = coroutine.wrap(f);
f_(...);
end
local buffers = {};
local function async_read(conn, len)
local buffer = buffers[conn] or "";
if type(len) == "number" then
while #buffer < len do
buffer = buffer..coroutine.yield();
end
local r = buffer:sub(1,len);
buffer = buffer:sub(len+1);
if buffer == "" then buffer = nil; end
buffers[conn] = buffer;
return r;
elseif len == "*l" or len == nil then
while true do
local line, rest = buffer:match("([^\n]\n)(.*)");
if line then
buffer = rest;
if buffer == "" then buffer = nil; end
buffers[conn] = buffer;
return line;
end
buffers[conn] = buffer..coroutine.yield();
end
end
end
local function async_write(client, data)
assert(client.network.socket:write(data));
end
coroutine.wrap(function ()
-- Create the redis client as normal here
-- (it must never be used outside this function)
-- Then do:
client.network.socket = wrap_blocking_socket(client.network.socket);
client.network.read = async_read;
client.network.write = async_write;
end)();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment