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
node-db: La excusa perfecta para hablar de C++ y Node.js
1. nodedb
La excusa perfecta para hablar de C++ y
Node.js
@mgiglesias
2. Se dice de mi
Que soy nerd
Que me gusta Apple
Sí, ¡ni te imaginás cuánto!
Que soy de opinar
@mgiglesias es una mescolanza preocupante
Que todos los lenguajes me quedan bien
Duh! ¿De qué era esta charla?
Que está en algún que otro proyecto FOSS
3. Se dice de mi
Le sobraba el tiempo, y arrancó WORKANA
Che, es http://workana.com
Le gusta Seinfeld
Y los zombies :/
Se mandó a mudar a Miramar
Se encerró en un baño de un avión
6. Propuesta nodedb
API C++ unificada
Separar lo intrínseco de los protocolos
Librerías DB blocking y non blocking
API en JS land sencillo
Performance
Solo relacionales
MySQL
Oracle
13. C++ en Node.js
Performance
Ojo, ¡no siempre!
Librerias C/C++
Código proprietario
Integración con otros lenguajes
Python en Node.js via boost:python?
21. Los métodos expuestos
v8::Handle<v8::Value> Cerveza::Tomar(const v8::Arguments& args) {
v8::HandleScope scope;
if (args.Length() != 1) {
THROW_EXCEPTION("Si no me decis cuantos litros que queres que haga?");
} else if (!args[0]>IsInt32()) {
THROW_EXCEPTION("Que te tomaste?");
} else if (args[0]>ToInt32()>Value() < 0) {
THROW_EXCEPTION("Limpia ese enchastre!")
}
Cerveza* cerveza = node::ObjectWrap::Unwrap<Cerveza>(args.This());
assert(cerveza);
cerveza>liters += (args[0]>ToInt32()>Value());
return scope.Close(v8::Undefined());
}
22. Los métodos expuestos
v8::Handle<v8::Value> Cerveza::Estado(const v8::Arguments& args) {
v8::HandleScope scope;
Cerveza* cerveza = node::ObjectWrap::Unwrap<Cerveza>(args.This());
assert(cerveza);
const char* estado;
if (cerveza>liters > 4) {
estado = "Me parece que te falto el agua para las macetas";
} else if (cerveza>liters > 2) {
estado = "Mas vale que no manejes";
} else if (cerveza>liters > 0) {
estado = "Segui tomando tranquilo";
} else {
estado = "Arranca a tomar de una vez!";
}
return scope.Close(v8::String::New(estado));
}
23. Y le decimos a Node
extern “C” void init(v8::Handle<v8::Object> target) {
Cerveza::Init(target);
}
NODE_MODULE(binding, init);
{
"targets": [
{
"target_name": "binding",
"sources": [ "cerveza.cc" ]
}
]
}
$ nodegyp configure build
info it worked if it ends with ok
make: Leaving directory `/home/mariano/Documents/Talks/JSConf/src/build'
info done ok
36. Conclusión
C++ sigue sirviendo para algo
libuv y libeio te simplifican la vida
¡No solo para Node.js eh!
Ojeá el fuente de Node. Hay cosas interesantes
ahí ;)
No minimices el poder de V8. Por algo se llama
V8
- Douglas Crockford: cuando hablas de JS, tenes que hablar de el no? Chuck norris de JS? - db-mysql.js: JS land. Extiende Query y Database de EventEmitter. Alli se llevaran los helper methods para escribir SQL - binding.cc: exports.Database - query.cc: exports Query - events.cc: usa el EventEmitter extendido de db-mysql.js
* Librerias: una cosa es implementar un cliente Paypal Payments Pro en Node, otra cosa es implementar un cliente Oracle puro en JS * Codigo proprietario: integracion con Ideafix
* Isaac Schlueter
* V8: Lo usamos para “convertir” datos JS en C++. Para exportar funciones. * libuv: nace como wrapper alrededor de libev, solo unix, para abstraer IOCP en Windows. Tiene thread pool, DNS asincrono, spawn de procesos, non blocking TCP * libeio: parecido a libev, manejo asincrono de file resources (open, close, read, write), ev_timer para timeouts * waf: via node-waf, hecho en Python. Syntaxis sencilla. * gyp: tb Python, mucho mas piola para cross-platform. En particular node-gyp es el equivalente a node-waf
* NODE_ADD_PROTOTYPE_METHOD: Define en cerveza.h que crea un nuevo prototype en base a un callback
* THROW_EXCEPTION: #define que RETORNA un v8::ThrowException
* NODE_MODULE: #define de node, Crea la estructura del modulo, dandole un nombre al modulo, y definiendo la funcion de inicio * EXTERN “C”: Le decimos a C++ que hay funciones C adentro
* uvComprar: en el thread pool * uvComprado: en el thread de V8
* Ref(): metemos una referencia asi no nos borra el garbage collector
* El callback se ejecuta cada vez que el evento sucede: en este caso cada vez que el FD es leible * revents: bitset de los eventos recibidos: EV_READ, EV_TIMEOUT, EV_ERROR, y otros