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 |
Sounds like a wonderful job! Congratulations to you!
On Thu, Dec 1, 2011 at 2:56 AM, Tim Caswell <[hidden email]> wrote: I've been holding off announcing my project on this list for some time -- Nothing is impossible. |
In reply to this post by Tim Caswell
On Wed, 30 Nov 2011 12:56:57 -0600
Tim Caswell <[hidden email]> wrote: > 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. release early, release often! build a community early ;-) > If you're familiar with nodejs, it's quite similar (...) it looks very cool, but i have to ask: why? is there anything about lua that makes it more appropriate to build this kind of technology vs javascript? anything with speed, reliability, available libraries? language features? or the fact that lua is a smaller language with a simpler implementation, and hence easier to work with to build this? on your github page I read "In initial benchmarking with a hello world server, this is between 2 and 4 times faster than nodeJS." do you know why this happens? can we conclude the lua jit runtime is just more efficient than js? (http://luajit.org/luajit.html also mentions something like that) Dieter |
On Thu, Dec 1, 2011 at 7:51 AM, Dieter Plaetinck <[hidden email]> wrote:
> On Wed, 30 Nov 2011 12:56:57 -0600 > Tim Caswell <[hidden email]> wrote: > >> If you're familiar with nodejs, it's quite similar (...) > > it looks very cool, but i have to ask: why? > is there anything about lua that makes it more appropriate to build this kind of technology vs javascript? > anything with speed, reliability, available libraries? language features? > or the fact that lua is a smaller language with a simpler implementation, and hence easier to work with to build this? > > on your github page I read "In initial benchmarking with a hello world > server, this is between 2 and 4 times faster than nodeJS." > do you know why this happens? can we conclude the lua jit runtime is just more efficient than js? > (http://luajit.org/luajit.html also mentions something like that) As I mentioned on the nodeJS mailing list: http://comments.gmane.org/gmane.comp.lang.javascript.nodejs/32664 1. Lua is not JavaScript. It's pretty darn close and I like both for unique reasons, but JavaScript is *far* more popular due to this thing we call the internet. 2. V8's JS to C++ conversion is really slow compared to luajit's Lua to C layer. Also V8 uses a lot more ram and starts up much slower. 3. Co-routines in Lua are really nice and with very little extra sugar make a simple, obvious, and effective way to write sync style code while living in an async world. Because of discovery #1, I don't think Luvit will ever become more popular than nodeJS, especially for anything web related. I see Luvit being used for things like mobile devices where performance *really* matters, JIT can be disabled (think iOS), and the built-in FFI makes SDL and openGL possible without bindings. I don't think it's fair or accurate to say that Luajit runs Lua faster than V8 runs JavaScript. It's much more complicated than that. Besides, in a Luvit program, most the time is not spend executing Lua code, it's making sys calls. Just for fun I benchmarked Luvit with and without Jit and it made only a 2% speed difference in the benchmark. -Tim Caswell |
Tim Caswell <[hidden email]> writes:
> Just for fun I benchmarked Luvit with and without Jit and it made only > a 2% speed difference in the benchmark. Of course the speed boost from using luajit will probably become more important as more complex applications are written... -Miles -- "Suppose He doesn't give a shit? Suppose there is a God but He just doesn't give a shit?" [George Carlin] |
In reply to this post by Tim Caswell
I really think Luvit is awesome and I feel bad for not yet having
found the time to play with it. I would divide all programms in roughly two big categories: * Scripts: the many variants of progeny of turing machines and computer science. program starts, gets a input, runs a while, makes output, finishes. * Interactives: programms keeps running until further notices and reacts on input. When input is user: GUIs, when it is network, filesystem or sockets: daemon. Most of the interactives have that big select() statement somewhere, with some mats for timeouts etc. and how many times has the wheel been reinvented around that? I invented my own version of that wheel a few times. For those class of programs Luvit could be *the* common framework. With such a framework it really gets easy to put off the shelf components into your application. Have a daemon for X? Now you can easily add an interface to query its status and control it via HTTP! Similar with asynchronous database IO, etc. - Axel |
In reply to this post by Dieter Plaetinck
On Thu, Dec 1, 2011 at 2:51 PM, Dieter Plaetinck <[hidden email]> wrote:
Coroutines. Look at any non-trivial node.js program, it's an awful mess of nested callbacks; very hard to read, impossible to maintain. Coroutines fix that, and that's a killer feature by itself.
Performance questions might also weight in favor Lua, but that's really secondary, compared to making user code maintainable.
|
On Thu, Dec 1, 2011 at 12:03 PM, Fabien <[hidden email]> wrote:
> Coroutines. Look at any non-trivial node.js program, it's an awful mess of > nested callbacks; very hard to read, impossible to maintain. Coroutines fix > that, and that's a killer feature by itself. this. callbacks-driven pseudomultitasking isn't anything new; it was the only way to get good responsiveness in classic MacOS. it was used only for slow I/O for a reason: it's _ugly_ current node.js proponents say that it's not so bad, or that you only have to shift your reasoning process. still, there are lots of people (and growing) that find it unmaintable for anything non-trivial. coroutines do fix that; up to a point. as the Copas (and Xavante) experience teach us, you have to be careful not to stall too long without I/O (to give a chance to the scheduler to yield). besides that, it's just as if you had multiprocessing without the overhead. BTW, how would Luvit compare with Xavante with a limited number of connections? i guess that over a hundred or so, any event-driven scheme surpasses the select()-based Copas, but below that, it's not so certain. There are also some event-library bindings, and i thing some of them included a Copas replacement that allowed you to run Xavante.... how's luvit different from that? -- Javier |
On Thu, Dec 1, 2011 at 4:01 PM, Javier Guerra Giraldez
<[hidden email]> wrote: > On Thu, Dec 1, 2011 at 12:03 PM, Fabien <[hidden email]> wrote: >> Coroutines. Look at any non-trivial node.js program, it's an awful mess of >> nested callbacks; very hard to read, impossible to maintain. Coroutines fix >> that, and that's a killer feature by itself. > > this. > > callbacks-driven pseudomultitasking isn't anything new; it was the > only way to get good responsiveness in classic MacOS. it was used only > for slow I/O for a reason: it's _ugly_ > > current node.js proponents say that it's not so bad, or that you only > have to shift your reasoning process. still, there are lots of people > (and growing) that find it unmaintable for anything non-trivial. > > coroutines do fix that; up to a point. as the Copas (and Xavante) > experience teach us, you have to be careful not to stall too long > without I/O (to give a chance to the scheduler to yield). besides > that, it's just as if you had multiprocessing without the overhead. I've been doing some light node.js development and I'm about to start a larger project. Since JavaScript was 'rediscovered' , I keep noting that many features that people enjoy about it have been in Lua for years too, and I'd rather write Lua than JavaScript (mostly for religious reasons, performance is far from limiting me on the simple tasks I have). I'll checkout Luvit as soon as possible, I've been dreaming about something like it for months now. Javier and Fabien, could you elaborate or send references as to why or how callback-oriented architectures seem to lend themslves to becoming unmaintainable? Cheers, -- Alessandro Delgado |
In reply to this post by Javier Guerra Giraldez
On Thu, Dec 1, 2011 at 3:01 PM, Javier Guerra Giraldez
<[hidden email]> wrote: > On Thu, Dec 1, 2011 at 12:03 PM, Fabien <[hidden email]> wrote: >> Coroutines. Look at any non-trivial node.js program, it's an awful mess of >> nested callbacks; very hard to read, impossible to maintain. Coroutines fix >> that, and that's a killer feature by itself. > > this. > > callbacks-driven pseudomultitasking isn't anything new; it was the > only way to get good responsiveness in classic MacOS. it was used only > for slow I/O for a reason: it's _ugly_ > > current node.js proponents say that it's not so bad, or that you only > have to shift your reasoning process. still, there are lots of people > (and growing) that find it unmaintable for anything non-trivial. > > coroutines do fix that; up to a point. as the Copas (and Xavante) > experience teach us, you have to be careful not to stall too long > without I/O (to give a chance to the scheduler to yield). besides > that, it's just as if you had multiprocessing without the overhead. > > BTW, how would Luvit compare with Xavante with a limited number of > connections? i guess that over a hundred or so, any event-driven > scheme surpasses the select()-based Copas, but below that, it's not so > certain. > > There are also some event-library bindings, and i thing some of them > included a Copas replacement that allowed you to run Xavante.... how's > luvit different from that? Could also be interesting to compare it with https://github.com/ignacio/LuaNode > > -- > Javier > -- -------------------------------------------------------------- EmmanuelOga.com - Software Developer |
Right, I keep forgetting to mention luanode. I don't mean to slight Ignacio.
First, the reason I made my own instead of contributing to his project is my goal was to learn libuv and lua bindings. What better way than to re-implement node in lua using libuv. Now that I've done most the prototyping, I've gotten busy with work and moving and other stuff so I'm presenting my work to the community to see how it stands on it's own. Luanode is probably more mature and certainly been around longer. It uses C++ and Boost ASIO. I use C and libuv which is the exact same library used by node itself. I haven't benchmarked luanode at all so I can't speak for it's performance. On Thu, Dec 1, 2011 at 2:44 PM, Emmanuel Oga <[hidden email]> wrote: > On Thu, Dec 1, 2011 at 3:01 PM, Javier Guerra Giraldez > <[hidden email]> wrote: >> On Thu, Dec 1, 2011 at 12:03 PM, Fabien <[hidden email]> wrote: >>> Coroutines. Look at any non-trivial node.js program, it's an awful mess of >>> nested callbacks; very hard to read, impossible to maintain. Coroutines fix >>> that, and that's a killer feature by itself. >> >> this. >> >> callbacks-driven pseudomultitasking isn't anything new; it was the >> only way to get good responsiveness in classic MacOS. it was used only >> for slow I/O for a reason: it's _ugly_ >> >> current node.js proponents say that it's not so bad, or that you only >> have to shift your reasoning process. still, there are lots of people >> (and growing) that find it unmaintable for anything non-trivial. >> >> coroutines do fix that; up to a point. as the Copas (and Xavante) >> experience teach us, you have to be careful not to stall too long >> without I/O (to give a chance to the scheduler to yield). besides >> that, it's just as if you had multiprocessing without the overhead. >> >> BTW, how would Luvit compare with Xavante with a limited number of >> connections? i guess that over a hundred or so, any event-driven >> scheme surpasses the select()-based Copas, but below that, it's not so >> certain. >> >> There are also some event-library bindings, and i thing some of them >> included a Copas replacement that allowed you to run Xavante.... how's >> luvit different from that? > > Could also be interesting to compare it with https://github.com/ignacio/LuaNode > >> >> -- >> Javier >> > > > > -- > -------------------------------------------------------------- > EmmanuelOga.com - Software Developer > > |
In reply to this post by Tim Caswell
2011/12/1 Tim Caswell <[hidden email]>:
> 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 > Hi Tim, My question is, does luvit can build on Windows? On Windows libuv use a complete different way to implement callback (use iocp on Windows other than epoll on Linux), so libuv will have no libev on Windows, I just get this link error: build/lenv.o:lenv.c:(.text+0x221): undefined reference to `setenv' build/lenv.o:lenv.c:(.text+0x270): undefined reference to `unsetenv' build/luv.o:luv.c:(.text+0x4): undefined reference to `ev_default_loop_ptr' build/luv.o:luv.c:(.text+0x31): undefined reference to `ev_run' build/luv.o:luv.c:(.text+0x4b): undefined reference to `ev_break' build/luv.o:luv.c:(.text+0x5f): undefined reference to `ev_default_loop' build/luv.o:luv.c:(.text+0x67): undefined reference to `ev_loop_destroy' build/luv.o:luv.c:(.text+0x7b): undefined reference to `ev_default_loop' build/luv.o:luv.c:(.text+0x83): undefined reference to `ev_loop_fork' build/luv.o:luv.c:(.text+0x96): undefined reference to `ev_iteration' build/luv.o:luv.c:(.text+0xa9): undefined reference to `ev_depth' build/luv.o:luv.c:(.text+0xbc): undefined reference to `ev_verify' collect2: ld returned 1 exit status make: *** [build/luvit] Error 1 the first two means MinGW on Windows missing setenv/unsetenv function, and others are ev functions. Does luvit planed to support Windows? |
Yes, it will build on windows and osx. I'm still working on getting
the build flags right. Bert has it working somewhat with mingw and his patch is in the ports branch. http://twitpic.com/7mr1zn Eventually luvit will use gyp the same as nodejs, libuv, and http_parser. On Thu, Dec 1, 2011 at 9:40 PM, Xavier Wang <[hidden email]> wrote: > 2011/12/1 Tim Caswell <[hidden email]>: >> 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 >> > > Hi Tim, > > My question is, does luvit can build on Windows? On Windows libuv use > a complete different way to implement callback (use iocp on Windows > other than epoll on Linux), so libuv will have no libev on Windows, I > just get this link error: > > build/lenv.o:lenv.c:(.text+0x221): undefined reference to `setenv' > build/lenv.o:lenv.c:(.text+0x270): undefined reference to `unsetenv' > build/luv.o:luv.c:(.text+0x4): undefined reference to `ev_default_loop_ptr' > build/luv.o:luv.c:(.text+0x31): undefined reference to `ev_run' > build/luv.o:luv.c:(.text+0x4b): undefined reference to `ev_break' > build/luv.o:luv.c:(.text+0x5f): undefined reference to `ev_default_loop' > build/luv.o:luv.c:(.text+0x67): undefined reference to `ev_loop_destroy' > build/luv.o:luv.c:(.text+0x7b): undefined reference to `ev_default_loop' > build/luv.o:luv.c:(.text+0x83): undefined reference to `ev_loop_fork' > build/luv.o:luv.c:(.text+0x96): undefined reference to `ev_iteration' > build/luv.o:luv.c:(.text+0xa9): undefined reference to `ev_depth' > build/luv.o:luv.c:(.text+0xbc): undefined reference to `ev_verify' > collect2: ld returned 1 exit status > make: *** [build/luvit] Error 1 > > the first two means MinGW on Windows missing setenv/unsetenv function, > and others are ev functions. > > Does luvit planed to support Windows? > > |
I just build luvit successfully on Window, on ports branch, and with
this change: $ git diff diff --git a/Makefile b/Makefile index 66c83f6..76e447f 100644 --- a/Makefile +++ b/Makefile @@ -80,14 +80,18 @@ ${LUADIR}/src/libluajit.a: mv deps/luajit/src/Makefile2 deps/luajit/src/Makefile # By default luajit builds a dll on Windows. Override this. if [ "${PLATFORM}" == "windows" ]; then \ - sed -e "s/#BUILDMODE= static/BUILDMODE= static/" -i deps/luajit/src/M - sed -e "s/BUILDMODE= mixed/#BUILDMODE= mixed/" -i deps/luajit/src/Mak + $(MAKE) -C ${LUADIR} BUILDMODE=static ; \ + else \ + $(MAKE) -C ${LUADIR} ;\ fi - $(MAKE) -C ${LUADIR} ${UVDIR}/uv.a: git submodule update --init ${UVDIR} - $(MAKE) -C ${UVDIR} uv.a + if [ "${PLATFORM}" == "windows" ]; then \ + $(MAKE) -C ${UVDIR} uv.a uname_S=MINGW ; \ + else \ + $(MAKE) -C ${UVDIR} uv.a ; \ + fi ${HTTPDIR}/http_parser.o: git submodule update --init ${HTTPDIR} diff --git a/deps/luajit b/deps/luajit --- a/deps/luajit +++ b/deps/luajit @@ -1 +1 @@ -Subproject commit e162d8cef0d1d62e3c43c23a6b28ebed68fdf7a0 +Subproject commit e162d8cef0d1d62e3c43c23a6b28ebed68fdf7a0-dirty SW@WXT410 /D/Work/Sources/luvit (ports) $ makefile is okay, why use gyp? gyp requires Python, it's big. 2011/12/2 Tim Caswell <[hidden email]>: > Yes, it will build on windows and osx. I'm still working on getting > the build flags right. Bert has it working somewhat with mingw and > his patch is in the ports branch. http://twitpic.com/7mr1zn > Eventually luvit will use gyp the same as nodejs, libuv, and http_parser. > > On Thu, Dec 1, 2011 at 9:40 PM, Xavier Wang <[hidden email]> wrote: >> 2011/12/1 Tim Caswell <[hidden email]>: >>> 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 >>> >> >> Hi Tim, >> >> My question is, does luvit can build on Windows? On Windows libuv use >> a complete different way to implement callback (use iocp on Windows >> other than epoll on Linux), so libuv will have no libev on Windows, I >> just get this link error: >> >> build/lenv.o:lenv.c:(.text+0x221): undefined reference to `setenv' >> build/lenv.o:lenv.c:(.text+0x270): undefined reference to `unsetenv' >> build/luv.o:luv.c:(.text+0x4): undefined reference to `ev_default_loop_ptr' >> build/luv.o:luv.c:(.text+0x31): undefined reference to `ev_run' >> build/luv.o:luv.c:(.text+0x4b): undefined reference to `ev_break' >> build/luv.o:luv.c:(.text+0x5f): undefined reference to `ev_default_loop' >> build/luv.o:luv.c:(.text+0x67): undefined reference to `ev_loop_destroy' >> build/luv.o:luv.c:(.text+0x7b): undefined reference to `ev_default_loop' >> build/luv.o:luv.c:(.text+0x83): undefined reference to `ev_loop_fork' >> build/luv.o:luv.c:(.text+0x96): undefined reference to `ev_iteration' >> build/luv.o:luv.c:(.text+0xa9): undefined reference to `ev_depth' >> build/luv.o:luv.c:(.text+0xbc): undefined reference to `ev_verify' >> collect2: ld returned 1 exit status >> make: *** [build/luvit] Error 1 >> >> the first two means MinGW on Windows missing setenv/unsetenv function, >> and others are ev functions. >> >> Does luvit planed to support Windows? >> >> > |
In reply to this post by Tim Caswell
Oh, My god, should I regard it as the third revolution of Lua.
1. lua language self, simple,clean and powerful 2. lua jit, speed 3. luvit, make writing pure lua program simple lua can be easily embed in program,but use pure lua write large project is a pain, why? it lack some import,efficiency,modern,standard lib like timer,net,asyn io... (so you still need make wheel or wrap some c/c++ libs); there are many ways in lua's module, no Unified. It seems luvit do it BOTH. |
I had this crazy idea. Now that Node is venturing into V8 isolates
(multithreading in isolated interpreter states) for clusters and the such with passing deeply frozen objects or string messages between the isolates. As far I undestood Lua_state is mostly the analogous thing to what V8 understands as isolate. Would it be possible / cool to have a Luvit Lua_state as Isolate within a Node.JS, or vice versa? One would throw out Lua's advantage of being small, since you'd have both interpreters running. But you keep fast, and would open to use any already written Node module functionality to be used from Luvit. Well you'd have to design some messaging between the Lua/JS isolates, but it should be possible, to use in Luvit say for example the mongodb interface written in javascript for node through the isolate Since Node is just developing isolates and doesn't have a defined interface for that yet, it might be a little early, but would make awesomesauce^2 if that would be possible. On Sun, Dec 4, 2011 at 4:59 AM, jiang yu <[hidden email]> wrote: > Oh, My god, should I regard it as the third revolution of Lua. > 1. lua language self, simple,clean and powerful > 2. lua jit, speed > 3. luvit, make writing pure lua program simple > > lua can be easily embed in program,but use pure lua write large > project is a pain, why? it lack some import,efficiency,modern,standard > lib like timer,net,asyn io... (so you still need make wheel or wrap > some c/c++ libs); there are many ways in lua's module, no Unified. It > seems luvit do it BOTH. > |
At least offer some kind of "pump" feature so it doesn't dominate the
main loop as is possible in Python's Twisted. In ruby EventMachine owns the main loop and makes it very hard to work with other code. On Sun, Dec 4, 2011 at 1:15 PM, Axel Kittenberger <[hidden email]> wrote: > I had this crazy idea. Now that Node is venturing into V8 isolates > (multithreading in isolated interpreter states) for clusters and the > such with passing deeply frozen objects or string messages between the > isolates. As far I undestood Lua_state is mostly the analogous thing > to what V8 understands as isolate. Would it be possible / cool to > have a Luvit Lua_state as Isolate within a Node.JS, or vice versa? > > One would throw out Lua's advantage of being small, since you'd have > both interpreters running. But you keep fast, and would open to use > any already written Node module functionality to be used from Luvit. > Well you'd have to design some messaging between the Lua/JS isolates, > but it should be possible, to use in Luvit say for example the mongodb > interface written in javascript for node through the isolate > > Since Node is just developing isolates and doesn't have a defined > interface for that yet, it might be a little early, but would make > awesomesauce^2 if that would be possible. > > On Sun, Dec 4, 2011 at 4:59 AM, jiang yu <[hidden email]> wrote: >> Oh, My god, should I regard it as the third revolution of Lua. >> 1. lua language self, simple,clean and powerful >> 2. lua jit, speed >> 3. luvit, make writing pure lua program simple >> >> lua can be easily embed in program,but use pure lua write large >> project is a pain, why? it lack some import,efficiency,modern,standard >> lib like timer,net,asyn io... (so you still need make wheel or wrap >> some c/c++ libs); there are many ways in lua's module, no Unified. It >> seems luvit do it BOTH. >> > |
For both luvit and nodejs, the main loop is libuv. I'm not sure if
it's possible to share a loop, but it would be a neat experiment for someone (not me) to try. The only way I can imagine node and luvit working together is with multiple processes and message passing through some common IPC. On Mon, Dec 5, 2011 at 9:08 AM, Daniel Aquino <[hidden email]> wrote: > At least offer some kind of "pump" feature so it doesn't dominate the > main loop as is possible in Python's Twisted. > > In ruby EventMachine owns the main loop and makes it very hard to work > with other code. > > > On Sun, Dec 4, 2011 at 1:15 PM, Axel Kittenberger <[hidden email]> wrote: >> I had this crazy idea. Now that Node is venturing into V8 isolates >> (multithreading in isolated interpreter states) for clusters and the >> such with passing deeply frozen objects or string messages between the >> isolates. As far I undestood Lua_state is mostly the analogous thing >> to what V8 understands as isolate. Would it be possible / cool to >> have a Luvit Lua_state as Isolate within a Node.JS, or vice versa? >> >> One would throw out Lua's advantage of being small, since you'd have >> both interpreters running. But you keep fast, and would open to use >> any already written Node module functionality to be used from Luvit. >> Well you'd have to design some messaging between the Lua/JS isolates, >> but it should be possible, to use in Luvit say for example the mongodb >> interface written in javascript for node through the isolate >> >> Since Node is just developing isolates and doesn't have a defined >> interface for that yet, it might be a little early, but would make >> awesomesauce^2 if that would be possible. >> >> On Sun, Dec 4, 2011 at 4:59 AM, jiang yu <[hidden email]> wrote: >>> Oh, My god, should I regard it as the third revolution of Lua. >>> 1. lua language self, simple,clean and powerful >>> 2. lua jit, speed >>> 3. luvit, make writing pure lua program simple >>> >>> lua can be easily embed in program,but use pure lua write large >>> project is a pain, why? it lack some import,efficiency,modern,standard >>> lib like timer,net,asyn io... (so you still need make wheel or wrap >>> some c/c++ libs); there are many ways in lua's module, no Unified. It >>> seems luvit do it BOTH. >>> >> > |
In reply to this post by jiang yu
I see my past experience with node and my preference for pure-scripted
programs is showing here in my project. Yes those were both explicit goals in making Luvit. My mantra whenever I stay up late writing C++ webgl bindings for nodejs or implementing luvit in C is "I write C so you don't have to". I want to provide all the primitives needed to make a program so that the script is all that's needed once the runtime is installed. On Sat, Dec 3, 2011 at 9:59 PM, jiang yu <[hidden email]> wrote: > Oh, My god, should I regard it as the third revolution of Lua. > 1. lua language self, simple,clean and powerful > 2. lua jit, speed > 3. luvit, make writing pure lua program simple > > lua can be easily embed in program,but use pure lua write large > project is a pain, why? it lack some import,efficiency,modern,standard > lib like timer,net,asyn io... (so you still need make wheel or wrap > some c/c++ libs); there are many ways in lua's module, no Unified. It > seems luvit do it BOTH. > |
In reply to this post by Tim Caswell
> The only way I can imagine node and luvit working together is with
> multiple processes and message passing through some common IPC. As far as I understood this is what they are planning for node 0.8 - from V8 isolate to V8 isolate. |
Free forum by Nabble | Edit this page |