20
Erlang и n2o web-разработка без JavaScript DevelCamp 2014 Татауров Евгений, Noda

Erlang и n2o. Web-разработка без JavaScript

Embed Size (px)

Citation preview

Page 1: Erlang и n2o. Web-разработка без JavaScript

Erlang и n2o web-разработка без

JavaScript

DevelCamp 2014 Татауров Евгений, Noda

Page 2: Erlang и n2o. Web-разработка без JavaScript

Erlang• Функциональный

• Динамически типизирован

• Лямбды

• Pattern matching

lists:map(fun(X) -> X*2 end, [4,8,15,16,23,42]).

double([H|T]) -> [2*H|double(T)];double([]) -> [].

Page 3: Erlang и n2o. Web-разработка без JavaScript

Erlang

• Процессы-акторы

• Message passing

• Распределенность из коробки

Page 4: Erlang и n2o. Web-разработка без JavaScript

Erlang

• Let it crash

• OTP

• Supervision tree

Page 5: Erlang и n2o. Web-разработка без JavaScript

n2o

• Cowboy (HTTP & WebSockets)

• Генерация HTML и обработчиков

• Scala Lift

• deferred javascript

Page 6: Erlang и n2o. Web-разработка без JavaScript
Page 7: Erlang и n2o. Web-разработка без JavaScript

n2o Elements#panel{id=Panel, body=#button{id=myButton, body= <<"OK">>, postback={ok, <<"INFO">>}}}

Page 8: Erlang и n2o. Web-разработка без JavaScript

n2o Elements#panel{id=Panel, body=#button{id=myButton, body= <<"OK">>, postback={ok, <<"INFO">>}}}

<div id="myPanel"><button id="myButton" type="button">OK</button></div>

Page 9: Erlang и n2o. Web-разработка без JavaScript

n2o Elements#panel{id=Panel, body=#button{id=myButton, body= <<"OK">>, postback={ok, <<"INFO">>}}}

<div id="myPanel"><button id="myButton" type="button">OK</button></div>document.getElementById('myButton').addEventListener('click',function (event){

ws.send(enc(tuple(atom('pickle'),bin('myButton'),bin('g2gCaAVkAAJldmQABWluZGV4aAJkAAJva20AAAAESU5GT2sACG15QnV0dG9uZAAFZXZlbnRoA2IAAAWFYgAKp5tiAACpXA=='),[tuple(tuple(utf8_toByteArray('myButton'), bin('detail')), event.detail)])));

})

Page 10: Erlang и n2o. Web-разработка без JavaScript

Мини-приложение + | +--------------+-+ | +----------------+ | web_app | instagram_app +-+--------------+ | | | WS | index | | | | +----+ | | | | Instagram | | | | | +----+ | | | | | | | | | +--------> +---+ | +---------------------+ HTTP POST | +^ +-+ +--------------+-+ | | | +----------------+ +----------------+ | | | <----------+ || +++--------------+ | | | | | |-------| loop | | | | | <----------+ +-------+> | | | | | | | | | | | | <---------+ | | | | | | | | <+-----------+ | | +-----------+ |   | +-+ | | | +----------------+ | | | | +---------------------+ |

Page 11: Erlang и n2o. Web-разработка без JavaScript

index.erlmain() -> #dtl{file="index", bindings=[{body, body()}]}.body() -> [#panel{id=butPanel, body=[ #button{id=catsButton, class= <<"btn">>, body= <<"show #cats”>>, postback={tag,<<"cats">>}}

]}, #panel{id=updater}].

Page 12: Erlang и n2o. Web-разработка без JavaScript

index.erl

event({tag, Tag}) -> wf:update(butPanel, #h1{body= << <<"#">>/binary, Tag/binary>>}), {ok, _Pid} = wf:async(Tag, fun() -> loop(updater, Tag) end), manager:subscribe(Tag), wf:reg(Tag).

Page 13: Erlang и n2o. Web-разработка без JavaScript

index.erlloop(Elem, Tag) -> receive {gproc_ps_event, {tag, Tag}, Text} -> insert_image(Elem, Text), wf:flush(Tag); timer:sleep(500), loop(Elem, Tag) end.

insert_image(Elem, Img) -> wf:insert_top(Elem, #panel{body=#panel{body=[ #link{href=maps:get(<<"link">>, Img), body=#image{src=maps:get(<<"url">>, maps:get(<<"low_resolution">>, maps:get(<<"images">>, Img))), }}]}}).

Page 14: Erlang и n2o. Web-разработка без JavaScript

Демо

Page 15: Erlang и n2o. Web-разработка без JavaScript

Вариант на Python

• asyncio (aiohttp + websockets)

• акторы, общение через очередь

• код на JavaScript

Page 16: Erlang и n2o. Web-разработка без JavaScript

@asyncio.coroutinedef handler(websocket, _path): new_image_receiver = ProcessQueue() SubscriptionManager.subscribe(TAG, new_image_receiver) while True: message = yield from new_image_receiver.receive() if not websocket.open: SubscriptionManager.unsubscribe(TAG, new_image_receiver) break yield from websocket.send(json.dumps(message))

var socket = new WebSocket("ws://127.0.0.1:8765");socket.onmessage = function (event) { var msg = JSON.parse(event.data); var img = document.createElement('img'); img.src = msg.images.low_resolution.url; var pics = document.getElementById('pics'); pics.insertBefore(img, pics.firstChild);}

Page 17: Erlang и n2o. Web-разработка без JavaScript

Производительность

Req/sec Latency

n2o 12450 21

aiohttp 530 117

tornado 1500 580

nginx 17600 49

wrk -t4 -c1000 -d30s http://127.0.0.1:8080

Page 18: Erlang и n2o. Web-разработка без JavaScript

Выводы• n2o быстр, как в плане работы, так и в плане разработки

• Можно не писать HTML и JavaScript

• Гибкость. Толстый клиент и REST endpoint, либо умный сервер и простой клиент.

• Все плюсы Erlang

Page 19: Erlang и n2o. Web-разработка без JavaScript

Выводы

• Свой DSL

• Нет нормальной документации API (но есть Nitrogen API)

• Сыроват, меняется, нет тестов.

Page 20: Erlang и n2o. Web-разработка без JavaScript

Ресурсы• http://synrc.com/apps/n2o/doc/web

• http://nitrogenproject.com

• Learn You Some Erlang for Great Good!

• Programming Erlang

• Erlang плагин для IDEA http://ignatov.github.io/intellij-erlang/

• https://github.com/etataurov/instastream