luvit: poeira estelar ziggy do nó

Recentemente, dei uma palestra no Open Source Bridge sobre
luvit , essa grande plataforma que estamos construindo que é como o node.js
usando apenas lua como linguagem de implementação.

De qualquer forma, meus slides estão disponíveis, mas eu queria criar uma
postagem de blog slide por slide com minhas anotações. Então aqui vai!

Além disso, se você estiver em Portland para a OSCON , vou dar uma palestra
sobre como estamos construindo um agente de monitoramento no servidor para o Rackspace
Cloud Monitoring em cima do luvit. Vou cobrir por que estávamos interessados ​​em
usar o luvit, como o luvit funciona e como o estamos incorporando em nosso
agente de monitoramento.

Visão geral não técnica

Luvit é uma plataforma para construir seu aplicativo de maneira orientada a eventos.

  • Esquelético
  • Desajeitado
  • Espaço temático (lua)
  • <3 comunidade
  • APIs de nó familiares

Notas: luvit é esquelético como Mr. Stardust e usa muito pouca memória.
luvit é um projeto jovem e ainda em crescimento, espere estranheza. lua significa lua em
português, por isso é temática espacial, assim como Ziggy. Há uma
grande comunidade com bom senso de humor (luv_handles é um ótimo
nome para estrutura de dados )


Visão geral técnica

  • lua usando luajit
  • pegada de memória baixa
  • Loop de evento orientado por I / O
  • API C pequena e simples
  • ligações cripto, ssl, zlib, json
  • suporte ao protocolo tcp, http, dns
  • Windows, Linux, FreeBSD e OSX

Notas: luajit é um jit vm realmente minúsculo para lua, super rápido. O
loop de eventos é orientado por E / S como nodejs. Ao contrário do node.js, lua tem uma
API C C realmente simples ; isso torna os módulos nativos um pouco mais fáceis de construir. luvit tem
os protocolos e criptografia que você esperaria. Além disso, funciona em todas as
plataformas principais . Essencialmente, uma plataforma de plataforma cruzada para construir seu
aplicativo.


Exemplo de servidor HTTP

local http = require("http")

http
.createServer(function (req, res)
local body = "Hello worldn"
res
:writeHead(200, {
["Content-Type"] = "text/plain",
["Content-Length"] = #body
})
res
:finish(body)
end):listen(8080)

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

Notas: Este código funciona hoje. Ele fornece um HTTP 1.1. servidor no 8080
que informa Olá!


Comunidade

  • http://luvit.io
  • Use solicitações / problemas de pull do github
  • IRC em freenode #luvit
  • Lista de correio do grupo Google para discussão
  • Base de código licenciada Apache 2.0
  • Grupo divertido de colaboradores

Notas: A comunidade tem as armadilhas usuais de uma
comunidade de código aberto . Há IRC, listas de discussão e a maior parte do desenvolvimento é conduzido
por meio de solicitações e problemas de pull do github.


História do projeto

  • Iniciado por Tim Caswell
  • Forte comunidade de colaboradores
    • Vladimir Dronnikov
    • Ryan Phillips
    • Paul Querna
    • Brandon Philips (eu)
  • Pessoas conduzindo o projeto em várias direções
    • Servidores de aplicativos HTTP
    • Demonstrações SDL no Linux
    • desenvolvimento de aplicativo para iPhone
    • Agente de monitoramento de nuvem

Notas: Há uma grande comunidade de pessoas trabalhando neste projeto.
A melhor parte é quantas pessoas estão interessadas em diferentes usos – não
apenas em coisas da web. Em particular, a Rackspace está interessada em um
agente de monitoramento de pegada de memória realmente pequeno .


Comparação com o nó

<ul>
<li> Máquina em nuvem de 256 MB executando Linux </li>
<li> HTTP Server Benchmark </li>
<li> 20 solicitações simultâneas </li>
<li> 20.000 solicitações no total </li>
<li> Simples GET </li>
</ul>
<ul class = “build”>
<li> luvit – 3,09 MB – ~ 4100 solicitações / segundo </li>
<li> nó – <b> 51,99 MB </b> – ~ 4900 solicitações / segundo </li>
</ul>

Notas: Usando um benchmark micro http, você pode ver que luvit usa
muito menos memória do que o nó. A velocidade regrediu, mas esperamos que possamos
recuperar a velocidade também 🙂


Lua


História

Notas: Lua tem um conjunto de recursos realmente simples que foi mantido pequeno ao se
concentrar em meta-recursos em vez de recursos de linguagem. Vemos isso na
forma como luvit implementa seu sistema Object. Confira a história da lua para
uma ótima aula de história


Lua – Primo brasileiro há muito perdido do Javascript

  • Linguagem dinâmica
  • Números de ponto flutuante apenas
  • Funções de primeira classe
  • Fechamentos lexicais
  • Meta-tabelas
  • Incorporável

Notas: Lua compartilha muitos recursos com javascript, como usar
apenas números de ponto flutuante , ser dinâmica e ter funções de primeira classe. É
como um primo brasileiro há muito perdido


Código de exemplo

GroundControl = {}

function GroundControl.new()
obj
= {}
obj
.heard_major_tom = false
setmetatable
(obj, { __index = GroundControl })
return obj
end

function GroundControl:heard()
print(self.heard_major_tom)
end

a
= GroundControl.new()

a
:heard()
a
.heard() -- this will error

Notas: Usando meta tabelas em lua, você pode implementar um sistema de objetos.
Essencialmente, o campo meta tabela __index diz a lua “se você não conseguir encontrar
o elemento solicitado nesta tabela, tente esta tabela”. Dessa forma, você pode
implementar objetos. Uma coisa a se notar sobre lua é que a
sintaxe a: hear () passa em a como “self” para a função ouvida. Chamar a.heard ()
causará um erro, já que self será nulo.


Características do luajit

  • x86, ARM, PPC, MIPS
  • API compatível com Lua 5.1
  • 125 K para VM, 85 K para compilador JIT
  • JIT inlines FFI

Notas: luajit é uma VM de rastreamento alternativa para lua que possui uma ótima
camada FFI . É pequeno e rápido.


libuv


Ideia básica

  • Dois tipos de eventos no loop:
    • E / S em descritores de arquivo
    • Cronômetros para eventos futuros
  • Chamadas de retorno são anexadas a esses eventos
  • epoll () / portas de conclusão / kqueue () esperar
  • o retorno de chamada é chamado no evento correto

Observações: Essencialmente, libuv é apenas um grande loop (consulte a próxima seção) que
executa a votação em um monte de descritores de arquivo com o tempo limite da votação
definido para o próximo cronômetro que precisa ser executado. Quando a pesquisa é concluída, um
retorno de chamada é feito para que o usuário possa manipular o evento. Eu tenho uma conversa no
libuv
que cobre todos os detalhes também


Pseudocódigo de loop de evento

for (;;) {
nfds
= poll(fds, maxfd, next_timer());
if (nfds == 0)
timer_callback
();

for(n = 0; n < nfds; ++n) {
callbacks
[fd]();
}
}

Outras plataformas construídas em libuv

Notas: Várias novas plataformas estão usando o libuv. Rust é uma nova
linguagem da Mozilla. candor é um subconjunto limitado de javascript.
luvmonkey é o macaco-aranha de Mozilla com libuv. http://julialang.org/
também está usando o libuv.


construindo amor


Acompanhe em casa

git clone git://github.com/luvit/luvit.git
cd luvit

gyp (todas as plataformas)

./configure
make
-C out
tools
/build.py test
./out/Debug/luvit
Welcome to the Luvit repl
>

make (linux, embutido)

make
make test

./build/luvit
Welcome to the Luvit repl
>

práticas de código luvit

http://ifup.org/slides/luvit-osb/examples

Notas: Esta seção cobrirá alguns exemplos de
código luvit de boa aparência


Sistema de objetos

local Object = require('core').Object
local Rectangle = Object:extend()
function Rectangle:initialize(w, h)
self.w = w
self.h = h
end
function Rectangle:getArea()
return self.w * self.h
end

local rect = Rectangle:new(3, 4)
p
(rect:getArea())

Notas: Lua não tem um sistema de objetos, então impelimos o nosso próprio
para fazer nossa herança de fluxo, emissor de evento, etc.


Sistema de Módulo

-- hello.lua
local hello = {}
hello
.world = function()
print("Hello World")
end
return hello

-- run.lua
local hello = require('hello')
hello
.world()

Notas: O sistema de módulos é muito semelhante aos nós. Basicamente, você
cria uma tabela de símbolos exportados e a retorna. vazar para o
escopo global é uma má prática require () retorna uma tabela que o arquivo importado
retorna


Exemplo JSON

local JSON = require('json')
local value = JSON.parse([[
{
"author": "Brandon Philips <brandon@ifup.org>",
"name": "luvit - node's Ziggy Stardust",
"description": "a talk about luvit"
}
]])

local json = JSON.stringify(value, {beautify=true,indent_string=" "});
print(json)

Notas: Luvit tem um analisador JSON usando yajl. Tem alguns recursos interessantes,
como permitir comentários


Cliente HTTP

local http = require('http')

local options = {
host
= "luvit.io",
port
= 80,
path
= "/"
}

local req = http.request(options, function (res)
res
:on('data', function (chunk)
p
("ondata", {chunk=chunk})
end)
end)

req
:done()

Notas: Este é um exemplo básico de cliente HTTP. Experimente no servidor
anterior 🙂


Comercial

Notas: Existem vários usuários de luvit hoje. Vamos ver alguns
deles


Módulos

Notas: há muitos módulos sendo construídos para luvit. E você sabe que uma
plataforma está ficando popular quando duas estruturas de teste surgem!


Aplicativos do mundo real

  • luvit.io está hospedado usando luvit
  • Agente Rackspace (consulte-me na OSCON)
  • Demonstrações do uso de SDL / GL e interação com Joystick

Trabalho futuro

  • Documentação!
  • Gerenciamento de pacotes lum
  • luvit como uma biblioteca
  • portas para OSX / iOS e loops de eventos Android

Observações: a documentação é crítica, muitas vezes contamos com nodejs.org, eek


Obrigado à comunidade luvit por todo o seu trabalho árduo. Também agradeço à
Rackspace por me deixar trabalhar abertamente.