node-db: La excusa perfecta para hablar de C++ y Node.js

download node-db: La excusa perfecta para hablar de C++ y Node.js

If you can't read please download the document

description

Un ejemplo de amistad entre C++ y Node.jsEsta charla introduce a node-db, una libreria para Node.js que busca ofrecer un soporte unificado a multiples bases de datos relacionales (MySQL y Oracle entre ellas), como una excusa para entrar al tema de fondo: el desarrollo de plugins para Node. js utilizando C++ y el motor V8

Transcript of node-db: La excusa perfecta para hablar de C++ y Node.js

  • 1. nodedbLaexcusaperfectaparahablardeC++yNode.js@mgiglesias

2. SedicedemiQuesoynerdQuemegustaAppleS,niteimaginscunto!Quesoydeopinar@mgiglesiasesunamescolanzapreocupanteQuetodosloslenguajesmequedanbienDuh!Dequeraestacharla?QueestenalgnqueotroproyectoFOSS 3. SedicedemiLesobrabaeltiempo,yarrancWORKANAChe,eshttp://workana.comLegustaSeinfeldYloszombies:/SemandamudaraMiramarSeencerrenunbaodeunavin 4. CortelchamulloDequvoyahablar?NodedbNode.js+C++ 5. HabaunavezunAlemn @felixge 6. PropuestanodedbAPIC++unificadaSepararlointrnsecodelosprotocolosLibrerasDBblockingynonblockingAPIenJSlandsencilloPerformanceSolorelacionalesMySQLOracle 7. Alaburar$npminstalldbmysqlvardbmysql=require(dbmysql);newdbmysql.Database({ hostname:localhost, user:root, password:password, database:node}).connect(function(error,server){ if(error){ thrownewError(ERROR:+error); } console.log(server);});{version:5.5.24,hostname:localhost,user:root, database:node} 8. Pooleandoconexionesvarmysql=require(dbmysql),generic_pool=require(genericpool);varpool=generic_pool.Pool({name:mysql,max:10,create:function(callback){newmysql.Database({}).connect(function(err,server){callback(err,this); });},destroy:function(db){db.disconnect();}});pool.acquire(function(err,db){pool.release(db);}); 9. Aconsultarsehadichodb.query().select(["id","user","email"]).from("users").where("roleIN?",[["administrator","user"]]).and("created>?",[newDate(2011,1,1)]).execute(function(error,rows,columns){if(error){console.log(ERROR:+error);return;}//Haceralgomasinteresante}); http://nodejsdb.org 10. Quhaydetrsdelteln?dbmysql.jsexports.Databaseexports.Querylib/nodedbbinding.cc,query.cc,events.ccconnection.cc,result.cc,exception.ccsrc/mysql.cc,query.cc connection.cc,result.cc 11. Enelfondo...JavascriptC++ V8:unamigo 12. C++?????? 13. C++enNode.jsPerformanceOjo,nosiempre!LibreriasC/C++CdigoproprietarioIntegracinconotroslenguajesPythonenNode.jsviaboost:python? 14. C++enNode.jsYaqueestamos,ledamosunamano 15. C++enNode.jsV8libuvlibeioYloquegustes...esC++despus detodo!waf/gyp 16. WINDOWS??????Birraparaelqueadivinadequpelculaesestafoto 17. Muertealosholamundosvarbinding=require(./build/Release/binding);cerveza=newbinding.Cerveza();console.log(cerveza.estado());cerveza.tomar(1);console.log(cerveza.estado());cerveza.tomar(2);console.log(cerveza.estado());cerveza.tomar(5);console.log(cerveza.estado());$nodetest.jsArrancaatomardeunavez!SeguitomandotranquiloMasvalequenomanejesMeparecequetefaltoelaguaparalasmacetas 18. Quganasdeunacerveza...#ifndefCERVEZA_H_#defineCERVEZA_H_#include#includeclassCerveza:publicnode::ObjectWrap{ public:staticvoidInit(v8::Handletarget); protected:longliters;Cerveza();staticv8::HandleNew(constv8::Arguments&args);staticv8::HandleTomar(constv8::Arguments&args);staticv8::HandleEstado(constv8::Arguments&args);};#endif 19. Quganasdeunacerveza...voidCerveza::Init(v8::Handletarget){ v8::HandleScopescope; v8::Localt=v8::FunctionTemplate::New(New); v8::PersistentconstructorTemplate; constructorTemplate=v8::Persistent::New(t); constructorTemplate>InstanceTemplate()>SetInternalFieldCount(1); NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,"tomar",Tomar); NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,"estado",Estado); target>Set(v8::String::NewSymbol("Cerveza"),constructorTemplate>GetFunction());}v8::HandleCerveza::New(constv8::Arguments&args){ v8::HandleScopescope; Cerveza*cerveza=newCerveza(); if(cerveza==NULL){THROW_EXCEPTION("Ops!Tamosenelhorno!")} cerveza>Wrap(args.This());returnscope.Close(args.This()); } 20. Quganasdeunacerveza... 21. Losmtodosexpuestosv8::HandleCerveza::Tomar(constv8::Arguments&args){v8::HandleScopescope;if(args.Length()!=1){THROW_EXCEPTION("Sinomedeciscuantoslitrosquequeresquehaga?");}elseif(!args[0]>IsInt32()){THROW_EXCEPTION("Quetetomaste?");}elseif(args[0]>ToInt32()>Value()liters+=(args[0]>ToInt32()>Value());returnscope.Close(v8::Undefined());} 22. Losmtodosexpuestosv8::HandleCerveza::Estado(constv8::Arguments&args){ v8::HandleScopescope; Cerveza*cerveza=node::ObjectWrap::Unwrap(args.This()); assert(cerveza); constchar*estado; if(cerveza>liters>4){ estado="Meparecequetefaltoelaguaparalasmacetas"; }elseif(cerveza>liters>2){ estado="Masvalequenomanejes"; }elseif(cerveza>liters>0){ estado="Seguitomandotranquilo"; }else{ estado="Arrancaatomardeunavez!"; }returnscope.Close(v8::String::New(estado));} 23. YledecimosaNodeexternCvoidinit(v8::Handletarget){Cerveza::Init(target);}NODE_MODULE(binding,init);{"targets":[{"target_name":"binding","sources":["cerveza.cc"]}]}$nodegypconfigurebuildinfoitworkedifitendswithokmake:Leavingdirectory`/home/mariano/Documents/Talks/JSConf/src/buildinfodoneok 24. libuvElmundonoesperfecto. Avecesnopodemoshacernonblocking....... sinthreads 25. libuvcerveza.comprar(function(){ cerveza.comprar(function(compradas){ console.log(Yacompre+compradas+cervezas); });});$nodetest.jsYacompre2cervezas 26. libuvuv_work_t*request=newuv_work_t();request>data=//.uv_queue_work(uv_default_loop(),request,uvComprar,uvComprado);uv_ref(uv_default_loop()); voiduvComprar(uv_work_t*uvRequest) voiduvComprado(uv_work_t*uvRequest)uv_unref(uv_default_loop()); 27. AcomprarcervezaclassCerveza:publicnode::ObjectWrap{ protected:longcompradas;pthread_mutex_tcompradasLock;structcompra_t{ Cerveza*cerveza; v8::Persistent*callback; v8::Persistentcontext;};staticv8::HandleComprar(constv8::Arguments&args); staticvoiduvComprar(uv_work_t*uvRequest); staticvoiduvComprado(uv_work_t*uvRequest);};Cerveza::Cerveza():litros(0),compradas(0){pthread_mutex_init(&(this>compradasLock),NULL);}Cerveza::~Cerveza(){ pthread_mutex_destroy(&(this>compradasLock)); } 28. v8::HandleCerveza::Comprar(constv8::Arguments&args){v8::HandleScopescope;Cerveza*cerveza=node::ObjectWrap::Unwrap(args.This());assert(cerveza);compra_t*compra=newcompra_t();if(compra==NULL){THROW_EXCEPTION("Sinespacio!")}cerveza>Ref();compra>context=v8::Persistent::New(args.This());compra>cerveza=cerveza;compra>callback=NULL;if(args.Length()>0){compra>callback=node::cb_persist(args[0]);}uv_work_t*req=newuv_work_t();req>data=compra;uv_queue_work(uv_default_loop(),req,uvComprar,uvComprado);uv_ref(uv_default_loop());returnscope.Close(v8::Undefined());} 29. voidCerveza::uvComprar(uv_work_t*uvRequest){ compra_t*compra=static_cast(uvRequest>data); assert(compra); pthread_mutex_lock(&(compra>cerveza>compradasLock)); compra>cerveza>compradas++; pthread_mutex_unlock(&(compra>cerveza>compradasLock));} 30. voidCerveza::uvComprado(uv_work_t*uvRequest){ v8::HandleScopescope;compra_t*compra=static_cast(uvRequest>data);assert(compra);uv_unref(uv_default_loop());compra>cerveza>Unref();if(compra>callback!=NULL){v8::Localargv[1]={ v8::Number::New(compra>cerveza>compradas)}; v8::TryCatchtryCatch; (*(compra>callback))>Call(compra>context,1,argv); if(tryCatch.HasCaught()){node::FatalException(tryCatch); }}compra>context.Dispose();if(compra>callback!=NULL){compra>callback>Dispose();} deletecompra;} 31. libeio libeioescomosimeteletransportaradellaburo albar.Cada5segundos 32. libeiocerveza.consultar(function(r){console.log(r);});$nodetest.jsJohnDoe 33. libeioev_io*ioRequest=newev_io();ev_init(ioRequest,eioConsultado);ev_io_set(ioRequest,fd,EV_READ);ev_io_start(EV_DEFAULT_UC_ioRequest);voideioConsultado(EV_P_ev_io*ioRequest,intrevents)ev_io_stop(EV_A_ioRequest); 34. v8::HandleCerveza::Comprar(constv8::Arguments&args){consulta>connection=mysql_init(NULL);mysql_real_connect(consulta>connection,"localhost","root","password","node",3306,NULL,0);mysql_send_query(consulta>connection,"SELECT*FROMusers",20); consulta>context=v8::Persistent::New(args.This()); consulta>cerveza=cerveza; consulta>callback=NULL; if(args.Length()>0){consulta>callback=node::cb_persist(args[0]); } consulta>cerveza>Ref(); ev_io*ioRequest=newev_io(); ioRequest>data=consulta; ev_init(ioRequest,eioConsultado); ev_io_set(ioRequest,consulta>connection>net.fd,EV_READ); ev_io_start(EV_DEFAULT_UC_ioRequest);} 35. voidCerveza::eioConsultado(EV_P_ev_io*ioRequest,intrevents){v8::HandleScopescope; consulta_t*consulta=static_cast(ioRequest>data); assert(consulta); ev_io_stop(EV_A_ioRequest); consulta>cerveza>Unref(); mysql_read_query_result(consulta>connection); MYSQL_RES*result=mysql_store_result(consulta>connection); assert(result); char**row=mysql_fetch_row(result); // mysql_free_result(result); mysql_close(consulta>connection);} 36. ConclusinC++siguesirviendoparaalgolibuvylibeiotesimplificanlavidaNosoloparaNode.jseh!OjeelfuentedeNode.Haycosasinteresantes ah;)NominimiceselpoderdeV8.Poralgosellama V8 37. Preguntas?:)www.workana.com @mgiglesias