Lua & co - @LDuboeuf - Novembre 2016
Lua & co
Lua & co - @LDuboeuf - Novembre 2016
About me
network & sys admin (far away)
programmer
And more recently,
Trainer/Facilitator @Afpa (adult training)
Lua & co - @LDuboeuf - Novembre 2016
Introduction to Lua
● Built in 1993 by Roberto Lerusalimschy, Waldemar Celes,
Luiz Henrique de Figueiredo – Brazil
● Lightweigth ( 24000 loc written in ANSI C), fast and easy to
integrate scripting language.
● Multi-paradigm : procedural, OO, fonctionnal
● Run on every Unix et Windows flavors, smartphones
(Android, iOS, Symbian, Windows Phone) , on embedded
( ARM, Rabbit), IBM mainframes, etc.
● C<->Lua bindings
● MIT License
Lua & co - @LDuboeuf - Novembre 2016
Where it is used and what for ?
redis Used as :
● Extension
● Monitoring
● Scripting (DSL)
● Proxy – Load balancing
● Cache management
● Web Application
Firewall
● Robotic
● Game play
● Etc...
Lua & co - @LDuboeuf - Novembre 2016
First step
https://gist.github.com/lduboeuf/66e87d2d18e26d0f48ec70539534e574
Lua & co - @LDuboeuf - Novembre 2016
First step...
https://gist.github.com/lduboeuf/13a8f75b1701e9204c1202d9bab7a482
Lua & co - @LDuboeuf - Novembre 2016
Metatable concept...
– Allows you to modify tables behavior
● Override « +, -, /, * » operators (example : table1 + table2 )
● Comparisons
● Inheritance, interface (OOP)
– Allows you to hook tables :
● When a new elements is added,
● When a table element is accessed,
● custom concatenation
● etc...
Lua & co - @LDuboeuf - Novembre 2016
OOP
Module pattern : Class like pattern :
Lua & co - @LDuboeuf - Novembre 2016
More about...
● Multithreading : coroutines :
– Not as OS multithreading, non pre-emptive. Allows you
non I/O blocking operations.
● Weirdness:
– Array indices start at 1 !
– Not equals : if (i~=1) then … end
– No ternary operator ( x>3 ? 1 : 0; )
– No increment shortcut : i = i + 1
–
Lua & co - @LDuboeuf - Novembre 2016
Luajit
● JIT compiler for lua (mainly created by Mike
Pall )
● Super fast! : 3 to 100x faster
● Small : < 100 KB
● Easy Native C library integration thanks to ffi
(foreign function include)
Lua & co - @LDuboeuf - Novembre 2016
Luajit : ffi - example
Lua & co - @LDuboeuf - Novembre 2016
Support & tools
● Tools:
– Package management : Luarocks
– Unit tests : « busted » or « luaunit » and more…
– Debugger :IDE ZeroBrane Studio
● Support
– Mailing list
– irc.freenode.net #lua
– Workshops
Lua & co - @LDuboeuf - Novembre 2016
Lua for the web
● Choose between :
– 100 % Lua :
● Xavante, Pegasus
– existing server extension for :
● LightHttpd, Apache, Nginx, Tornado...
– nodeJs like :
● Luvit
Lua & co - @LDuboeuf - Novembre 2016
Openresty
Openresty = Nginx + Luajit + Modules
Lua & co - @LDuboeuf - Novembre 2016
Nginx
● HTTP server, reverse proxy, mail proxy
● Asynchronous
● Low memory footprint
● Modular
● Extensible
Lua & co - @LDuboeuf - Novembre 2016
Nginx model
Source : http://www.aosabook.org/en/nginx.html
Lua & co - @LDuboeuf - Novembre 2016
Nginx – min server
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
server {
listen 8000;
location / {
index index.html;
root public/;
}
}
$> curl http://0.0.0.0:8000/index.html
Lua & co - @LDuboeuf - Novembre 2016
Openresty
● Created and maintained mainly by Yichun Zhang (@agentzh)
.( Taobao.com then Clouflare )
● In production on high trafic site (Alibaba group, Clouflare,...)
● Non blocking I/O modules for :
● Memcached
● Redis
● MySQL / Drizzle
● PostgreSQL
● Websockets, CLI, Json, etc..
Lua & co - @LDuboeuf - Novembre 2016
Openresty
● Allows you to scripts in Lua during Nginx phases
– Init phase
– Rewrite phase.
– Access phase.
– Content phase.
– Log phase
– And more…
● Lua API to access Ngninx environment
Lua & co - @LDuboeuf - Novembre 2016
Openresty
● Lua code is executed within workers
Lua & co - @LDuboeuf - Novembre 2016
Openresty – Hello world
location /hellolua {
default_type 'text/plain';
content_by_lua_block {
local name = ngx.var.arg_name or "Anonymous"
ngx.say("Hello, ", name, "!")
};
}
$> curl http://localhost/hellolua?name=Lua
Hello, Lua
Lua & co - @LDuboeuf - Novembre 2016
Openresty : load external module
location /xxxx {
rewrite_by_lua_file /path/to/rewrite.lua;
access_by_lua_file /path/to/access.lua;
content_by_lua_file /path/to/content.lua;
}
● Modules are loaded once per worker at first request
Lua & co - @LDuboeuf - Novembre 2016
Openresty : sub request
location / {
content_by_lua '
local res = ngx.location.capture("/memcached",
{ args = { cmd = "incr", key = ngx.var.uri } }
)
';
}
location /memcached {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
memc_pass 127.0.0.1:11211;
}
Lua & co - @LDuboeuf - Novembre 2016
Openresty – cosocket
● Non blocking I/O thanks to Cosocket library :
– TCP or Unix Domain sockets
– Allows you to write asynchronous sequential code !
(bye bye callback hell)
– « Keepalive » for reuse connections.
Lua & co - @LDuboeuf - Novembre 2016
Openresty : TCP client
location /memcached {
content_by_lua_block {'
local sock = ngx.socket.connect("127.0.0.1", 11211)
sock:send("SET foo bar 3600rn")
local line = sock:receive()
if line then
ngx.say(line)
end
sock:setkeepalive()
};
}
$> curl http://localhost/memcached
STORED
Lua & co - @LDuboeuf - Novembre 2016
Openresty : mysql
location /todos {
content_by_lua_block {
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
ngx.say("failed to instantiate mysql: ", err)
return
end
db:set_timeout(1000) -- 1 sec
--connect…
local res, err, errcode, sqlstate = db:query("select * from tasks")
if not res then
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
return
end
local cjson = require "cjson"
ngx.say("result: ", cjson.encode(res))
} ;
}
Lua & co - @LDuboeuf - Novembre 2016
Openresty : mini app
location /api/v0.1/todos {
default_type application/json;
content_by_lua_block {
local todo_api = require "todo-app"
--get location after /api/v0.1/todos
local sub_loc = string.sub(ngx.var.request_uri, string.len(ngx.var.location)+1)
if sub_loc == "" then sub_loc = "/" end
local router = require "router"
local r = router.new()
r:get("/", todo_api.getAll)
r:post("/", todo_api.create)
r:delete("/:id", todo_api.delete)
r:put("/:id", todo_api.update)
--execute routes
r:execute(ngx.var.request_method, sub_loc, ngx.req.get_uri_args())
}
● }
https://github.com/lduboeuf/openresty-todo-app
Lua & co - @LDuboeuf - Novembre 2016
Openresty - tools
● Real time profiling
● Test suite
● Package manager (OPM)
● Mailing list
Lua & co - @LDuboeuf - Novembre 2016
Openresty : built with
● Lapis ( http://leafo.net/lapis/ ) = openresty +
libs utils + templating html + sessions
● Sailor ( http://sailorproject.org/ ) = MVC, routing,
templating, model generator, etc.
Lua & co - @LDuboeuf - Novembre 2016
Bonus !
Lua & co - @LDuboeuf - Novembre 2016
Protocol agnostic : Luvit
● Built by Tim Caswell (@creationix) , a former NodeJs contributor.
● In production within Rackspace for their monitoring agents.
● Primary goal was to port Node to Lua : Memory gain : 20x !
● Built on top of LibUV (same as Node) : event loop,
Asynchronous I/O,…
● Use of OpenSSL, zlib libs.
● Allows you to build self-executable apps, fast and lightweight.
Lua & co - @LDuboeuf - Novembre 2016
Luvit
● We can create apps « nodeJs like » (call-back based)
or with sequential code (thanks to coroutine)
● Lit : Package manager, repository and compiler
git clone git@github.com:creationix/hexes.git
cd hexes
lit install
lit make
./hexes
lit make lit://creationix/hexes
./hexes
When published to repository, this is simple as :
Example : compile and execute
Lua & co - @LDuboeuf - Novembre 2016
Luvit : example
https://github.com/creationix/hexes
Lua & co - @LDuboeuf - Novembre 2016
Luvit
● Really cool if :
– Not afraid of sporadic docs
– Not afraid with programing your own connector ;-)
( a connector for Prostgresql, Redis exist )
● Community : freenode IRC #luvit , mailing list
https://luvit.io
Lua & co - @LDuboeuf - Novembre 2016
Voilà, merci !
http://openresty.org/en/
http://luajit.org/
https://luvit.io/
https://www.lua.org/

Introduction to Lua Luajit Openresty Luvit

  • 1.
    Lua & co- @LDuboeuf - Novembre 2016 Lua & co
  • 2.
    Lua & co- @LDuboeuf - Novembre 2016 About me network & sys admin (far away) programmer And more recently, Trainer/Facilitator @Afpa (adult training)
  • 3.
    Lua & co- @LDuboeuf - Novembre 2016 Introduction to Lua ● Built in 1993 by Roberto Lerusalimschy, Waldemar Celes, Luiz Henrique de Figueiredo – Brazil ● Lightweigth ( 24000 loc written in ANSI C), fast and easy to integrate scripting language. ● Multi-paradigm : procedural, OO, fonctionnal ● Run on every Unix et Windows flavors, smartphones (Android, iOS, Symbian, Windows Phone) , on embedded ( ARM, Rabbit), IBM mainframes, etc. ● C<->Lua bindings ● MIT License
  • 4.
    Lua & co- @LDuboeuf - Novembre 2016 Where it is used and what for ? redis Used as : ● Extension ● Monitoring ● Scripting (DSL) ● Proxy – Load balancing ● Cache management ● Web Application Firewall ● Robotic ● Game play ● Etc...
  • 5.
    Lua & co- @LDuboeuf - Novembre 2016 First step https://gist.github.com/lduboeuf/66e87d2d18e26d0f48ec70539534e574
  • 6.
    Lua & co- @LDuboeuf - Novembre 2016 First step... https://gist.github.com/lduboeuf/13a8f75b1701e9204c1202d9bab7a482
  • 7.
    Lua & co- @LDuboeuf - Novembre 2016 Metatable concept... – Allows you to modify tables behavior ● Override « +, -, /, * » operators (example : table1 + table2 ) ● Comparisons ● Inheritance, interface (OOP) – Allows you to hook tables : ● When a new elements is added, ● When a table element is accessed, ● custom concatenation ● etc...
  • 8.
    Lua & co- @LDuboeuf - Novembre 2016 OOP Module pattern : Class like pattern :
  • 9.
    Lua & co- @LDuboeuf - Novembre 2016 More about... ● Multithreading : coroutines : – Not as OS multithreading, non pre-emptive. Allows you non I/O blocking operations. ● Weirdness: – Array indices start at 1 ! – Not equals : if (i~=1) then … end – No ternary operator ( x>3 ? 1 : 0; ) – No increment shortcut : i = i + 1 –
  • 10.
    Lua & co- @LDuboeuf - Novembre 2016 Luajit ● JIT compiler for lua (mainly created by Mike Pall ) ● Super fast! : 3 to 100x faster ● Small : < 100 KB ● Easy Native C library integration thanks to ffi (foreign function include)
  • 11.
    Lua & co- @LDuboeuf - Novembre 2016 Luajit : ffi - example
  • 12.
    Lua & co- @LDuboeuf - Novembre 2016 Support & tools ● Tools: – Package management : Luarocks – Unit tests : « busted » or « luaunit » and more… – Debugger :IDE ZeroBrane Studio ● Support – Mailing list – irc.freenode.net #lua – Workshops
  • 13.
    Lua & co- @LDuboeuf - Novembre 2016 Lua for the web ● Choose between : – 100 % Lua : ● Xavante, Pegasus – existing server extension for : ● LightHttpd, Apache, Nginx, Tornado... – nodeJs like : ● Luvit
  • 14.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty Openresty = Nginx + Luajit + Modules
  • 15.
    Lua & co- @LDuboeuf - Novembre 2016 Nginx ● HTTP server, reverse proxy, mail proxy ● Asynchronous ● Low memory footprint ● Modular ● Extensible
  • 16.
    Lua & co- @LDuboeuf - Novembre 2016 Nginx model Source : http://www.aosabook.org/en/nginx.html
  • 17.
    Lua & co- @LDuboeuf - Novembre 2016 Nginx – min server worker_processes 1; error_log logs/error.log; events { worker_connections 1024; } http { server { listen 8000; location / { index index.html; root public/; } } $> curl http://0.0.0.0:8000/index.html
  • 18.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty ● Created and maintained mainly by Yichun Zhang (@agentzh) .( Taobao.com then Clouflare ) ● In production on high trafic site (Alibaba group, Clouflare,...) ● Non blocking I/O modules for : ● Memcached ● Redis ● MySQL / Drizzle ● PostgreSQL ● Websockets, CLI, Json, etc..
  • 19.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty ● Allows you to scripts in Lua during Nginx phases – Init phase – Rewrite phase. – Access phase. – Content phase. – Log phase – And more… ● Lua API to access Ngninx environment
  • 20.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty ● Lua code is executed within workers
  • 21.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty – Hello world location /hellolua { default_type 'text/plain'; content_by_lua_block { local name = ngx.var.arg_name or "Anonymous" ngx.say("Hello, ", name, "!") }; } $> curl http://localhost/hellolua?name=Lua Hello, Lua
  • 22.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty : load external module location /xxxx { rewrite_by_lua_file /path/to/rewrite.lua; access_by_lua_file /path/to/access.lua; content_by_lua_file /path/to/content.lua; } ● Modules are loaded once per worker at first request
  • 23.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty : sub request location / { content_by_lua ' local res = ngx.location.capture("/memcached", { args = { cmd = "incr", key = ngx.var.uri } } ) '; } location /memcached { set $memc_cmd $arg_cmd; set $memc_key $arg_key; memc_pass 127.0.0.1:11211; }
  • 24.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty – cosocket ● Non blocking I/O thanks to Cosocket library : – TCP or Unix Domain sockets – Allows you to write asynchronous sequential code ! (bye bye callback hell) – « Keepalive » for reuse connections.
  • 25.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty : TCP client location /memcached { content_by_lua_block {' local sock = ngx.socket.connect("127.0.0.1", 11211) sock:send("SET foo bar 3600rn") local line = sock:receive() if line then ngx.say(line) end sock:setkeepalive() }; } $> curl http://localhost/memcached STORED
  • 26.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty : mysql location /todos { content_by_lua_block { local mysql = require "resty.mysql" local db, err = mysql:new() if not db then ngx.say("failed to instantiate mysql: ", err) return end db:set_timeout(1000) -- 1 sec --connect… local res, err, errcode, sqlstate = db:query("select * from tasks") if not res then ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".") return end local cjson = require "cjson" ngx.say("result: ", cjson.encode(res)) } ; }
  • 27.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty : mini app location /api/v0.1/todos { default_type application/json; content_by_lua_block { local todo_api = require "todo-app" --get location after /api/v0.1/todos local sub_loc = string.sub(ngx.var.request_uri, string.len(ngx.var.location)+1) if sub_loc == "" then sub_loc = "/" end local router = require "router" local r = router.new() r:get("/", todo_api.getAll) r:post("/", todo_api.create) r:delete("/:id", todo_api.delete) r:put("/:id", todo_api.update) --execute routes r:execute(ngx.var.request_method, sub_loc, ngx.req.get_uri_args()) } ● } https://github.com/lduboeuf/openresty-todo-app
  • 28.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty - tools ● Real time profiling ● Test suite ● Package manager (OPM) ● Mailing list
  • 29.
    Lua & co- @LDuboeuf - Novembre 2016 Openresty : built with ● Lapis ( http://leafo.net/lapis/ ) = openresty + libs utils + templating html + sessions ● Sailor ( http://sailorproject.org/ ) = MVC, routing, templating, model generator, etc.
  • 30.
    Lua & co- @LDuboeuf - Novembre 2016 Bonus !
  • 31.
    Lua & co- @LDuboeuf - Novembre 2016 Protocol agnostic : Luvit ● Built by Tim Caswell (@creationix) , a former NodeJs contributor. ● In production within Rackspace for their monitoring agents. ● Primary goal was to port Node to Lua : Memory gain : 20x ! ● Built on top of LibUV (same as Node) : event loop, Asynchronous I/O,… ● Use of OpenSSL, zlib libs. ● Allows you to build self-executable apps, fast and lightweight.
  • 32.
    Lua & co- @LDuboeuf - Novembre 2016 Luvit ● We can create apps « nodeJs like » (call-back based) or with sequential code (thanks to coroutine) ● Lit : Package manager, repository and compiler git clone git@github.com:creationix/hexes.git cd hexes lit install lit make ./hexes lit make lit://creationix/hexes ./hexes When published to repository, this is simple as : Example : compile and execute
  • 33.
    Lua & co- @LDuboeuf - Novembre 2016 Luvit : example https://github.com/creationix/hexes
  • 34.
    Lua & co- @LDuboeuf - Novembre 2016 Luvit ● Really cool if : – Not afraid of sporadic docs – Not afraid with programing your own connector ;-) ( a connector for Prostgresql, Redis exist ) ● Community : freenode IRC #luvit , mailing list https://luvit.io
  • 35.
    Lua & co- @LDuboeuf - Novembre 2016 Voilà, merci ! http://openresty.org/en/ http://luajit.org/ https://luvit.io/ https://www.lua.org/