n2o most powerful erlang web framework · spa angular meteor ember chaplin brunch d3 knockout react...

40
N2O Most Powerful Erlang Web Framework @5HT

Upload: others

Post on 23-Jul-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

N2OMostPowerful

ErlangWebFramework

@5HT

Page 2: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

HowdoIshotWeb?

Page 3: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

MicroREST

PythonFlaskRubySinatraPHPSilex

ScalaScalatra

Page 4: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

ConcurrencyinMindRubyCelluloid

PHPReactPHPphpDaemonJava+ScalaPlay

Page 5: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

SPA

AngularMeteorEmberChaplinBrunch

D3KnockoutReactBackbonejQuery

Page 6: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

FunctionalDSLScalaLift

ErlangNitrogenHaskellBlazeHtmlOCamlOcsigenF#WebSharper

Page 7: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

Clojure

LaserEnliveCompojureRing

HiccupClojureScriptOmhttp-kitalephnoir

JVM

Page 8: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery
Page 9: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

ElixirWeberdefaction(_,conn)do{:render,[project:"simpleTodo"],[]}enddefadd([body:body],_conn)do{:json,[response:"ok"],[{"Content-Type","application/json"}]}enddefwrong(_,_)do{:redirect,"/"}end

Page 10: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

ErlangChicagoBoss

DTLEngineDatabaseConnectivity

PubSubRubyonRailslike

Page 11: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

NitrogenN2O~2000LOCOneProcessperConnectionBinaryPageConstruction

ZeroBridgeGProcPub/Sub

WebSockets,KVSDB

Page 12: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

TunedLayers

staticanddynamicRoutingPathcleanedQueryParser

SessionCookiesstoredinETScachedDTLTemplates

optimizedNitrogenDSLrenderingHTMLElementsbinaries

JavaScriptActionsdeferred

Page 13: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

LayersPerformancecomponentsTCPconn(K)PHP5FCGISimpleScript<?php?>5 NitrogenNosession,NoDSL,DTL1 N2OSessions,DSL,DTL 7N2OSessions,noDSL,DTL10N2ONoSessions,noDSL,DTL13

Onsamemachine rawwebserverperformancemeasuredwithwrk: NGINX--60K Cowboy--30K

Page 14: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

Cowboy--30K

MeasuringToolsrequestspages/seclatency(ms)wrk15K13628.8618.88ab10K5464.63190httperf10K3623.50200siege1K884.51430

Onsamemachinerawwebserverperformancemeasuredwithwrk:NGINX--60K

Page 15: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

DecreasingLatencyFrom2xto∞DeliverHTMLASAP

DeferredJavaScriptdeliveryafterWebSocket

connectionestablished<script>TransitionProcess='<0.7780.5>'</script>

socket.send(["N2O",TransitionProcess]).

Page 16: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

DynamicHTMLcow

Page 17: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

StaticHTMLnginx

Page 18: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

SPAandDTLRenderbothHTMLandJavaScriptusingDSL:

#button{postback=login,source=[user,pass]}

OrrenderonlyJavaScript..

#button{render=script,id=ElementId,

postback=login,source=[user,pass]}

..whenyoudevelopSPA

Page 19: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

Render<inputvalue="Login"id="temp563149"type="button"/>

$('#temp563149').bind('click',functionanonymous(event)ws.send(Bert.encodebuf({source:Bert.binary('temp563149'),pickle:Bert.binary('g2gCaINoAmgEZAA...'),linked:[Bert.tuple(Bert.atom('user'),utf8.toByteArray($('#user').val())),Bert.tuple(Bert.atom('pass'),utf8.toByteArray($('#pass').val()))]}));});

Page 20: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

#diagram{},#histogram{},#monitor{}].

ElementsPlugyourJavaScriptcontrols

body()->[#textboxlist{},#grid{},

andtalkwiththemusingBERTthroughWebSockets

Page 21: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

ActionsClientUpdatesaresentasActions

whichareevaluatedasJavaScriptstrings

render_action(Record)->wf:f("alert(\"~s\");",[wf:js_escape(Record#alert.text)]).

wf:wire(#alert{text="Hello,World!"}).

ElementrendercouldcreateActionsActioncouldincluderenderedElements

TriggeredActionmaysendEvents

Page 22: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

JSCompiler200LOCPreservesSemantics

-compile({parse_transform,shen}).M=lists:foldl(fun(X,Acc)->Acc+Xend,0,[1,2,3,4]),

$erlcsample.erl

m=[1,2,3,4].reduce(function(x,acc){returnacc+x;},0);

Page 23: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

1.HumanReadableOutput2.NoRuntimes

3.StrongDynamicTyping4.CompactLanguage,SaneSyntax

SynrcShen,JScala[1,2,3,4]TypeScript[1,2,4] CoffeeScript,LiveScript [1,2,3]Ur,Fay,Roy,Elm,Haxe,F*,WebSharper[3,4]ClojureScript[4]OberonJS[1,3,4]Wisp[1,2,4]

Page 24: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

WhyErlangtoJS?ValidationRulesBusinessRulesPrototyping

StaticContentGenerationSingleEnvironment

Page 25: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

SPAReactERLUser=#react{render=fun(This)->#h1{body=value(email,This)}end},

CommentList=#react{props=[{data,[]}],render=fun(This)->Users=lists:map(fun(Item)->User#react{props=Item}end,value(data,This)),Usersend},

Page 26: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

SPAReactJSvaruser=React.createClass({render:function(){returnReact.DOM.h1(null,value('email',this));}});

varcommentlist=React.createClass({props:{data:[]},render:function(){varusers=value('data',this).map(function(item){returnuser({props:item});});returnusers;}});

Page 27: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

ErlangASTCMPTBLBrace(Joxa/wErlangAST)

Elixir,Erlang

SynrcShenJavaScriptCompilercanhandleeachErlanglanguagethat

compilestoErlangAST*

Page 28: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

DTLSamplemain()->Body=wf:render(body()),[#dtl{file="login",bindings=[{body,Body}]}].body()->[#span{text="Login:"},#textbox{id=user},#span{text="Pass:"},#password{id=pass},#button{text="Login",postback=login,source=[user,pass]}].event(login)->wf:user(wf:q(user)),wf:redirect().

Page 29: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

N2OinElixirdefmoduleSample.Indexdo

def event(:init)do:wf.reg(:room)enddef event({:chat,pid})dopid<-{:message,:wf.q(:message)}enddef event(e)do:wf.info('UnknownEvent~p',[e])enddef main()do:dtl.new(file:"index",bindings:[title: "ElixirN2O",body:body()])enddef body()do{:ok,pid}=: wf.async(fn()->loop()end)[: div.new(id::history),: textbox.new(id::message),: button.new(id::send,body:"Chat",postback:{:chat,pid},source:[:message])]end

def loop()doreceivedo{: message,message}->:wf.insert_bottom(:history,[:span.new(body:message),:br.new()]): wf.flush(:room)unknown->: wf.info('UnknownLooperMessage~p' ,[unknown])end loop()endend

Page 30: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

N2OinJoxa(nslispchat(requireerlangjoxa-coren2owf))(defn+body()[(n2o/panel{:id:history})(n2o/textbox{:id:message})(n2o/button{:id:send}{:body"Chat"}{:postback:chat}{:source[:message]})])(defn+main()[(n2o/dtl{:app:n2o_sample}{:file"index"}{:bindings[{:title"Title"}{:body(body)}]})])(defn+speak(m)(wf/insert_bottom:history(n2o/span{:bodym})))(defn+event(body)(casebody(:init(speak["Hello"(n2o/br)]))(:chat(speak[(wf/q:message)(n2o/br)]))))(defn+test()(do(event:init)(wf/info"hello~p~n"[(main)])))

Page 31: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

JSONproplists<->JSON243x

LibraryTypeEncDec---------------------------------jsonxCNIF1048998jiffyCNIF26522234yaws2Erlang1420812653XenReadyjsonerlErlang1454914899mochijson2Erlang1678716512jsxErlang2718818333

Page 32: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

JSONPTproplists<=>#rec{}

-module(users).-behaviour(n2o_rest).-compile({parse_transform,n2o_rest}).-include("users.hrl").-rest_record(user).

from_json(Proplist,#user{})->#user{}.to_json(Record)->proplist().

Page 33: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

-compile({parse_transform,n2o_rest}).-include("users.hrl").-rest_record(user).

init()->ets:new(users,[public,named_table,{keypos,#user.id}]).populate(Users)->ets:insert(users,Users).exists(Id)->ets:member(users,wf:to_list(Id)).get()->ets:tab2list(users).get(Id)->[User]=ets:lookup(users,wf:to_list(Id)),User.delete(Id)->ets:delete(users,wf:to_list(Id)).post(#user{}=User)->ets:insert(users,User);post(Data)->post(from_json(Data,#user{})).

RESTSample

Page 34: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

KVSRESTAPIPOST/PUTkvs:add(#user{}).DELETEkvs:remove(user,2).PUT/PATCHkvs:put(#user{id=2}).GET kvs:entries(Feed,user).GET kvs:get(user,2).GET kvs:all(user).

Page 35: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

EventsFromJavaScript

EverythingissentasanEvent

Postbackevent/1Control control_event/2API api_event/3

HandleeventsinErlang...

Page 36: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

EventsNatureEventsareenvelopedbyBERT

as#ev{}-record(ev,{name::api_event|control_event|event|atom(),payload,trigger,module::atom()}).

Youcandefineyourownentrypoints

Page 37: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

PostbackEventsCreatePageLogicwithPostbackEventsevent/1

main()->[#button{postback=login}].

event(login)->wf:info("LoggedUser:~p",[wf:user()]).

Page 38: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

ControlEventsHandleDatafromControlswithControlEventscontrol_event/2

render_element(E=#myelement{})->do_render(E).

control_event(Trigger,Data)->wf:info("ReceivedData~pfromJavaScriptControl~p",[Data,Trigger]).

...whenyoucteateyourownElements

Page 39: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

APIEventsWireErlangandJavaScriptwith

APIEventsapi_event/3

main()->wf:wire(#api{name=notify,tag=api3}),[].

api_event(Event,Args,Req)->wf:info("ReceivedfromJavaScript:~p",[Args]).

document.notify('HellofromJavaScript').

Page 40: N2O Most Powerful Erlang Web Framework · SPA Angular Meteor Ember Chaplin Brunch D3 Knockout React Backbone jQuery

CommunitySources

https://github.com/5HT/n2o

HTMLandTeXHandbookhttp://synrc.com/framework/web/

IRCFreeNode #N2O