lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I've been holding off announcing my project on this list for some time
since it's not 1.0 yet, but now I realise that won't happen any time
soon.

I'm proud to announce my latest hack, Luvit
<https://github.com/luvit/luvit>.  As described in the subject, this
is basically luajit2 + libuv (the event loop library behind nodejs).
It compiles as a single executable just like nodejs and can run .lua
files.  What makes it different from the stock luajit distribution is
it has several built-in modules added and some slightly different
semantics.

If you're familiar with nodejs, it's quite similar.  If not, the basic
idea is you have a single threaded event loop that never blocks on I/O
wait.  This enables you to write high-performance network programs
using a simple callback based programming style.  Since lua, the
language has native co-routines, you can also use those instead of
callbacks if that's your preference.  Luvit supports both.

I changed some lua semantics slightly to make modules make sense.  For
example, require search paths work like in node.  This means that you
can do relative requires to the file that's doing the requiring.
There is no user-modifiable search path, and normal requires search
for bundled modules starting at the caller and going up the filesystem
tree. (./modules, ../modules, ../../modules, etc)  All modules (binary
included) must return a table that is their value.  Modules are not to
pollute the global environment by putting stuff there.  Also the lua
io module is disabled since it is not compatible with the non-blocking
architecture.

Enough of the incompatibilities, now for the abilities!

- HTTP server and client
- TCP server and client
- All sorts of filesystem operations
- Some UDP support
- PIPE streams
- TTY streams
- Timers and intervale
- Robust and portable module system that encourages sane dependencies

To write a simple http hello-world server, you simply have to write
the following lua script:

    local HTTP = require("http")
    local Utils = require("utils")

    HTTP.create_server("0.0.0.0", 8080, function (req, res)
      local body = Utils.dump({req=req,headers=req.headers}) .. "\n"
      res:write_head(200, {
        ["Content-Type"] = "text/plain",
        ["Content-Length"] = #body
      })
      res:finish(body)
    end)

    print("Server listening at http://localhost:8080/";)

This is the response given when hitting with curl:

<http://creationix.com/luvitresponse.png>

Notice that we're not running as a CGI script to apache or anything
like that.  The lua script *is* the http server.  You get your
callback called every time an http request is made to the server.  See
more examples in the github repo
<https://github.com/luvit/luvit/tree/master/examples>

I won't waste everyone's time describing the type of system I'm trying
to build.  It's explained well in this recent blog post about node
http://substack.net/posts/b96642

Luvit has a nice colorized repo that is imho much easier to use than
the stock one in lua.  Return values are automatically shown
(including nil values).  The p() function is like print, but pretty
prints data as seen in this debug dump of an http server.
<http://creationix.com/luvit2.png>

Luvit is complete enough for many classes of applications.  It's not
as finished as I'd like and since it's just a hobby I haven't had much
time to work on it in the last month.  I encourage people to play with
it and see if they like it.  If there is interest then I can make time
to continue working on it.

-Tim Caswell

http://howtonode.org/
http://github.com/creationix
http://twitter.com/creationix