Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Show HN: LuaJIT FFI binding to libuv with coroutines (github.com/pguillory)
101 points by pguillory on Aug 28, 2014 | hide | past | favorite | 35 comments


Great work on the bindings.

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.

http://luajit.org/sponsors.html


While I agree that LuaJIT is great piece of work, the linked page says Mike is not accepting sponsorships at this time and there doesn't seem to be any way to fund him.


The best way to contribute to LuaJIT seems to be to learn its internals and make contributions, or to fund somebody else to do so. Mike encouraged this when he gave a talk on LuaJIT in Zurich last year. His own commercial ambitions seem to be already satisfied at the moment.


In your "See Also", you missed my favorite UV+Lua combination: https://github.com/richardhundt/luv/tree/ray (note the branch). It too uses the Lua coroutines but has a specially-built scheduler. How does this compare to that effort, specifically, how are the libuv event loop and the Lua coroutines combined?


Thanks for pointing that out. I was going to ask why it appears to have stalled a year ago, but I guess the author got distracted by something shiny:

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.

[1] https://github.com/richardhundt/shine#introduction

[2] https://news.ycombinator.com/item?id=8191345


I might be remembering it wrong, but iirc it so transpired that there was a thread on the Lua mailing list about the unfortunate clash in the name 'luv'.

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.


Thanks very much.


Thanks, I've added it to the list.

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...


How is this different from https://github.com/luvit/luv (part of http://luvit.io/)?


In addition to what benjaminva said, luv uses callbacks (like Node.js), whereas this uses coroutines. So for example with luv you might do something like:

    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.


luv is a lua bindung for the libuv library which means that it uses all the C API provided by the lua language to code the interface between C functions and lua functions.

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.


I've used openresty compiled with LuaJIT (nginx+LuaJIT) for some low latency high scale services in the past. I wonder would this make it so I could ditch nginx and go pure LuaJIT and still have that level of performance? Has anyone done performance testing of this against Nginx+LuaJIT (openresty)?


While I agree it'd be interesting to see how libuv event loop performs against the nginx event loop, keep in mind that if you're deploying a web application, nginx has a ton of other uses. For example if you need SSL termination, caching, static files served, url rewriting, rate limiting, etc., you're better off having nginx handle those then re-implementing all of that yourself. Also, unless you harden your HTTP server, you'll likely need to proxy it behind nginx anyway (as is the case with, say, tornado).

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've implemented pure LuaJIT servers (without libuv) which compare favorably to nginx in terms of latency and performance. But you should consider whether or not you will need SSL\HTTPS support. libuv is only an IO loop and will not provide this out of the box like nginx. Encryption is important and non-trivial. Most of the projects I've seen end up back at C and embedded Lua\LuaJIT (similar to OpenResty) rather than writing bindings and tests for SSL in the LuaJIT FFI because of this.


As @pygy_ said, check out http://turbolua.org/


This would get toasted by Nginx right now. I'm on step 2 of "make it work, make it right, make it fast." There's a lot of low hanging fruit, like string concatenation, small mallocs, 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.


There's http://turbolua.org/ that's inspired by Tornado.


In principle I prefer this to Luvit since the later uses a customized version of LuaJIT( https://github.com/luvit/luvit/wiki/lua-to-luvit ) while this one uses vanilla LuaJIT.


Lua's somewhat diasporic community gives it an unfortunately high barrier to entry. It might be helpful to post this in /r/lua or on lua-l; disclosure: I moderate the former and it's pretty small.


I've been a serious Lua coder for 4 years now, and I have to say that I agree with you about the diaspora factor - Lua users aren't loud, they just get on with using this extraordinarily powerful, small, tight tool. I feel like Lua-heads actively resist forming big community and loud forums, because - like so many other powerful tools - there is a covetous factor involved. ;)

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.


Lua pretty much has the same problem as Tcl. Two embedded scenarios don't share much with each other, and quite often you're not even allowed to use outside code -- or even share some of your own.

OpenResty has been around for a while, but then again, it's not like Aolserver helped Tcl a lot in the end.


Where is the promised "synchronous syntax"? The first example show an ordinary async call with a callback.


What restrictions are there that keep regular Lua from being able to run this?


It's built on the LuaJIT FFI, which regular Lua doesn't have. There's an implementation of the LuaJIT FFI's API for regular Lua (https://github.com/jmckaskill/luaffi), but the performance is underwhelming.


Why use 'regular Lua'?

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. :)


nodelua?


There is luvit, too


I work on a C/C++/Lua server stack, so this is right up my alley. But as a MSVC native I'd have to spend hours trying to decipher your Makefile to port it to Windows before I could even evaluate it.


Use virtualbox, create a small Linux VM, and run it alongside whatever else you've got on your machine. Its simple enough that its sort of a duh - if you were really interested, you could get the VM and bootable Linux dev environment running in less than an hour. I'd be surprised if it took you 20 minutes to look at this stack, build and compile, and learn about it that way...


It is written for Linux, changing the Makefile is not going to change this.


Upon further reading I agree. But seeing as how Lua, LuaJIT, libuv are all cross-platform, there is hope that such a tool can be as well.


I've only tried building it on OS X and Linux so far. As far as I know, basically everything but the build process is compatible with Windows. I'll look into it when I get a chance.


Out of curiosity, what do you use as your primary editor/IDE for Lua?


Not the OP, and not a Windows user at all (100% Linux, except for OSX buildservers..) but I can answer as an experienced Lua developer the "IDE Question" in two ways, for Lua scope of application, as well as developer-style, is universal:

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 ..


Visual Studio or Notepad++. Lua for us is mostly for testing, so it doesn't take much.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: