Show HN: LuaJIT FFI binding to libuv with coroutines
github.com
github.com
Also for those of you not aware of the great work Mike Pall has done on LuaJIT you should really look into it. He's done amazing work virtually all himself. Please consider donating to the project to help fund and support Mike.
Mike offers all of his work under a BSD license so the community can freely, without restriction, use his research and developments.
https://github.com/richardhundt/shine
Shine appears to address a similar need as the luv "ray" branch, _without_ libuv, with a modified version of LuaJIT[1]. I wonder if the author plans to patch LuaJIT upstream?
A recent HN discussion[2] left me wondering where to look for a high-quality well-maintained lua "stdlib". luvit appears to be an entire distribution with its own package manager instead of luarocks/moonrocks. I'm now looking at luv and luajit-libuv. shine looks like a very interesting alternative, but the modified LuaJIT makes it problematic for deploying to users who want to use system-provided LuaJIT.
richardhundt/luv is older of the two pieces of software but Richard graciously offered to yield (pun intended) the name to luvit folks and continued to develop on his code and ideas under a new name, shine. richardhundt/luv is more than an obvious wrapper over libuv whcih is what luvit/luv intended to be.
Please bear in mind I might have got the exact events (Gawd, pun again, this time unintended) wrong, but if you are interested you will be able to find this on the lua mailing list archives.
In luajit-libuv, when Lua code makes an async request to libuv, it passes async.resume as the callback. Then it calls async.yield(), which stores the current coroutine in a global lookup table by unique ID, puts the ID in the request's data field, and yields the coroutine. When libuv completes the request, it calls async.resume, which gets the ID out of the request's data field, looks up the coroutine, and resumes it. [1]
So it's actually pretty simple, and still probably more complicated than it needs to be. libuv does all the scheduling.
I've been studying Ray, going over luv_fiber.c and luv_thread.c trying to understand them enough to give you a comparison, but to be honest I don't get it. It wraps coroutines, does something related to scheduling... I dunno.
[1]: https://github.com/pguillory/luajit-libuv/blob/master/src/uv...
Here we have a FFI-binding which means that only the header of the C functions are sufficient for the ffi library to handle all conversions of variables to and from the lua environment. Additional interface related functions are coded in lua instead of C.
Luajit provides a powerful FFI implementation which makes it very easy to provide interfaces to C libraries. However, it is not part of the vanilla lua implementation which is why both versions have their reasons to exist.
fs.readFile(filename, function(err, data)
-- remember to check err
end)
With this binding the code would look like: local data = fs.readfile(filename)
-- err was raised if one occurred
With coroutines, you can use exceptions and for/while loops and they continue to work as you would expect.It seems to me the argument for OpenResty is: if you already have nginx in your stack, you might as well run your app in it as well.
(not saying a libuv based server in lua is pointless, I mean I've used tornado behind nginx. I also concede it would be super useful for non-web servers (say, a custom protocol/IMAP/DNS/etc.))
I started out working with OpenResty, and it still makes the most sense for a project that leans heavily on the functionality of Nginx.
But when things as elegant as luvit/lujit-libuv hit the scene, its hard not to agree with those who have the temerity to proclaim Lua's immense usefulness to the masses ..
Lua just plain kicks ass, its really all there is to it.
OpenResty has been around for a while, but then again, it's not like Aolserver helped Tcl a lot in the end.
Never forget that Lua doesn't have to be an operating-system-available install; the LuaVM lives in many, many other contexts than scriptability and execution-at-shell. Lua-based applications can be bundled into any .EXE, .app, .deb, .ipa package, as required .. and in this case, the place for it is in a very small, tight Linux VM node host, which can be spooled in the thousands at will/as needed.
Opinion: As I personally have a strong interest in seeing Lua (and things like it) being used as the principle wrapping for next-gen OS's, stuff like this is terribly exciting. :)
In a GUI scenario, I use SublimeText for all lua projects and as a cross-platform, 'responsible editor', it provides a nice development enviroment. You can set up buildtools, run them, get output, etc. Generally for my needs it works fabulously. File->Open {directory of main.lua}, then everything works - Global Definitions, Refactoring, etc. Find definitions, see global usage, etc. Code-Completion gradually starts to work more and more, but I don't rely on such 'features' in an IDE. I feel comfortable with little help from an IDE.
In a non-GUI scenario (embedded), I use vim+cscope as my principle IDE. Same idea as ST - open the folder containing main.lua, work from there. Cscope works for Lua, and is also amazing if you do FFI hacking, too .. well generally cscope is my grep, but if I don't have it, of course grep works too ..