Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An advanced Node.js driver for RethinkDB with a connection pool, support for streams etc.

License

NotificationsYou must be signed in to change notification settings

GetFeedback/rethinkdb-js

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build StatusCoverage Status

A Node.js driver for RethinkDB with more advanced features.

Install

npm install rethinkdbdash

Note: Therethinkdbdash-unstable package is a relic from the past (rethinkdb < 1.13).

Quick start

Rethinkdbdash uses almost the same API as the official driver. Please refer totheofficial driver's documentationfor all the ReQL methods (the methods used to build the query).

The main differences are:

  • You need to execute the module when you import it:
varr=require('rethinkdbdash')();// With the official driver:// var r = require('rethinkdb');
  • Connections are managed by the driver with an efficient connection pool.Once you have imported the driver, you can immediately run queries,you don't need to callr.connect, or pass a connection torun.
varr=require('rethinkdbdash')();r.table('users').get('orphee@gmail.com').run().then(function(user){// ...}).error(handleError)
  • Cursors are coerced to arrays by default
varr=require('rethinkdbdash')();r.table('data').run().then(function(result){assert(Array.isArray(result))// true// With the official driver you need to call// result.toArray().then(function(result2) {//   assert(Array.isArray(result2))// })});

Drop in

You can replace the official driver with rethinkdbdash by just replacing

varr=require('rethinkdb');

With:

varr=require('rethinkdbdash')({pool:false,cursor:true});

If you want to take advantage of the connection pool, refer to the next section.

From the official driver

To switch from the official driver to rethinkdbdash and get the most of it,here are the few things to do:

  1. Change the way to import the driver.
varr=require('rethinkdb');

To:

varr=require('rethinkdbdash')();// Or if you do not connect to the default local instance:// var r = require('rethinkdbdash')({servers: [{host: ..., port: ...}]});
  1. Remove everything related to a connection:
r.connect({host: ...,port: ...}).then(function(connection){connection.on('error',handleError);query.run(connection).then(function(result){// console.log(result);connection.close();});});

Becomes:

query.run().then(function(result){// console.log(result);});
  1. Remove the methods related to the cursor. This typically involvesremovingtoArray:
r.table('data').run(connection).then(function(cursor){cursor.toArray().then(function(result){// console.log(result):});});

Becomes

r.table('data').run().then(function(result){// console.log(result);});

Using TLS Connections

Note: Support for a TLS proxy is experimental.

RethinkDB does not support TLS connections to the server yet, but in case you wantto run it over an untrusted network and need encryption, you can easily run a TLS proxyon your server with:

vartls=require('tls');varnet=require('net');vartlsOpts={key:'',// You private keycert:''// Public certificate};tls.createServer(tlsOpts,function(encryptedConnection){varrethinkdbConn=net.connect({host:'localhost',port:28015});encryptedConnection.pipe(rethinkdbConn).pipe(encryptedConnection);}).listen(29015);

And then safely connect to it with thetls option:

varr=require('rethinkdbdash')({port:29015,host:'place-with-no-firewall.com',ssl:true});

ssl may also be an object that will be passed as theoptions argument totls.connect.

New features and differences

Rethinkdbdash ships with a few interesting features.

Importing the driver

When you import the driver, as soon as you execute the module, you will createa default connection pool (except if you pass{pool: false}. The options youcan pass are:

  • db:<string> - The default database to use if none is mentioned.
  • user:<string> - The RethinkDB user, default value is admin.
  • password:<string> - The password for the user, default value is an empty string.
  • discovery:<boolean> - When true, the driver will regularly pull data from the tableserver_status tokeep a list of updated hosts, defaultfalse
  • pool:<boolean> - Set it tofalse, if you do not want to use a connection pool.
  • buffer:<number> - Minimum number of connections available in the pool, default50
  • max:<number> - Maximum number of connections available in the pool, default1000
  • timeout:<number> - The number of seconds for a connection to be opened, default20
  • pingInterval: - if> 0, the connection will be pinged everypingInterval seconds, default-1
  • timeoutError:<number> - Wait time before reconnecting in case of an error (in ms), default 1000
  • timeoutGb:<number> - How long the pool keep a connection that hasn't been used (in ms), default 60*60*1000
  • maxExponent:<number> - The maximum timeout before trying to reconnect is 2^maxExponent x timeoutError, default 6 (~60 seconds for the longest wait)
  • silent: - console.error errors, defaultfalse
  • servers: an array of objects{host: <string>, port: <number>} representing RethinkDB nodes to connect to
  • optionalRun: - iffalse, yielding a query will not run it, defaulttrue
  • log: - will be called with the log events by the pool master

In case of a single instance, you can directly passhost andport in the top level parameters.

Examples:

// connect to localhost:8080, and let the driver find other instancesvarr=require('rethinkdbdash')({discovery:true});// connect to and only to localhost:8080varr=require('rethinkdbdash')();// Do not create a connection poolvarr=require('rethinkdbdash')({pool:false});// Connect to a cluster seeding from `192.168.0.100`, `192.168.0.101`, `192.168.0.102`varr=require('rethinkdbdash')({servers:[{host:'192.168.0.100',port:28015},{host:'192.168.0.101',port:28015},{host:'192.168.0.102',port:28015},]});// Connect to a cluster containing `192.168.0.100`, `192.168.0.100`, `192.168.0.102` and// use a maximum of 3000 connections and try to keep 300 connections available at all time.varr=require('rethinkdbdash')({servers:[{host:'192.168.0.100',port:28015},{host:'192.168.0.101',port:28015},{host:'192.168.0.102',port:28015},],buffer:300,max:3000});

You can also pass{cursor: true} if you want to retrieve RethinkDB streams as cursorsand not arrays by default.

Note: The option{stream: true} that asynchronously returns a stream is deprecated. UsetoStream instead.

Note: The option{optionalRun: false} will disable the optional run for all instances of the driver.

Note: Connections are created with TCP keep alive turned on, but some routers seem to ignore this setting. To makesure that your connections are kept alive, set thepingInterval to the interval in seconds you want thedriver to ping the connection.

Note: The error__rethinkdbdash_ping__ is used for internal purposes (ping). Do not use it.

Connection pool

As mentioned before,rethinkdbdash has a connection pool and manage all the connectionsitself. The connection pool is initialized as soon as you execute the module.

You should never have to worry about connections in rethinkdbdash. Connections are createdas they are needed, and in case of a host failure, the pool will try to open connections with anexponential back off algorithm.

The driver execute one query per connection. Now thatrethinkdb/rethinkdb#3296is solved, this behavior may be changed in the future.

Because the connection pool will keep some connections available, a script will notterminate. If you have finished executing your queries and want your Node.js scriptto exit, you need to drain the pool with:

r.getPoolMaster().drain();

The pool master by default will log all errors/new states onstderr. If you do notwant to pollutestderr, passsilent: true when you import the driver andprovide your ownlog method.

r=require('rethinkdbdash')({silent:true,log:function(message){console.log(message);}});
Advanced details about the pool

The pool is composed of aPoolMaster that retrieve connections forn pools wheren is the number ofservers the driver is connected to. Each pool is connected to a unique host.

To access the pool master, you can call the methodr.getPoolMaster().

The pool emits a few events:

  • draining: whendrain is called
  • queueing: when a query is added/removed from the queue (queries waiting for a connection), the size of the queue is provided
  • size: when the number of connections changes, the number of connections is provided
  • available-size: when the number of available connections changes, the number of available connections is provided

You can get the number of connections (opened or being opened).

r.getPoolMaster().getLength();

You can also get the number of available connections (idle connections, withouta query running on it).

r.getPoolMaster().getAvailableLength();

You can also drain the pool as mentionned earlier with;

r.getPoolMaster().drain();

You can access all the pools with:

r.getPoolMaster().getPools();

The pool master emits thehealthy when its state change. Its state is defined as:

  • healthy when at least one pool is healthy: Queries can be immediately executed or will be queued.
  • not healthy when no pool is healthy: Queries will immediately fail.

A pool being healthy is it has at least one available connection, or it was justcreated and opening a connection hasn't failed.

r.getPoolMaster().on('healthy',function(healthy){if(healthy===true){console.log('We can run queries.');}else{console.log('No queries can be run.');}});
Note about connections

If you do not wish to use rethinkdbdash connection pool, you can implement yours. Theconnections created with rethinkdbdash emits a "release" event when they receive anerror, an atom, or the end (or full) sequence.

A connection can also emit a "timeout" event if the underlying connection times out.

Arrays by default, not cursors

Rethinkdbdash automatically coerce cursors to arrays. If you need a raw cursor,you can call therun command with the option{cursor: true} or import thedriver with{cursor: true}.

r.expr([1,2,3]).run().then(function(result){console.log(JSON.stringify(result))// print [1, 2, 3]})
r.expr([1,2,3]).run({cursor:true}).then(function(cursor){cursor.toArray().then(function(result){console.log(JSON.stringify(result))// print [1, 2, 3]});})

Note: If a query returns a cursor, the connection will not bereleased as long as the cursor hasn't fetched everything or has been closed.

Readable streams

Readable streams can besynchronously returned with thetoStream([connection]) method.

varfs=require('fs');varfile=fs.createWriteStream('file.txt');varr=require('rethinkdbdash')();r.table('users').toStream().on('error',console.log).pipe(file).on('error',console.log).on('end',function(){r.getPool().drain();});

Note: The stream will emit an error if you provide it with a single value (streams, arraysand grouped data work fine).

Note:null values are currently dropped from streams.

Writable and Transform streams

You can create aWritableorTransform streams bycallingtoStream([connection, ]{writable: true}) ortoStream([connection, ]{transform: true}) on a table.

By default, a transform stream will return the saved documents. You can return the primarykey of the new document by passing the optionformat: 'primaryKey'.

This makes a convenient way to dump a file your database.

varfile=fs.createReadStream('users.json')vartable=r.table('users').toStream({writable:true});file.pipe(transformer)// transformer would be a Transform stream that splits per line and call JSON.parse.pipe(table).on('finish',function(){console.log('Done');r.getPool().drain();});

Optionalrun withyield

Thethen andcatch methods are implemented on aTerm - returned by any methodslikefilter,update etc. They are shortcut forthis.run().then(callback) andthis.run().catch(callback).

This means that you canyield any query without callingrun.

varbluebird=require('bluebird');varr=require('rethinkdbdash')();bluebird.coroutine(function*(){try{varresult=yieldr.table('users').get('orphee@gmail.com').update({name:'Michel'});assert.equal(result.errors,0);}catch(err){console.log(err);}});

Note: You have to start Node >= 0.11 with the--harmony flag.

Global default values

You can set the maximum nesting level and maximum array length on all your queries with:

r.setNestingLevel(<number>)
r.setArrayLimit(<number>)

Undefined values

Rethinkdbdash will ignore the keys/values where the value isundefined insteadof throwing an error like the official driver.

Better errors

Backtraces

If your query fails, the driver will return an error with a backtrace; your querywill be printed and the broken part will be highlighted.

Backtraces in rethinkdbdash are tested and properly formatted. Typically, long backtracesare split on multiple lines and if the driver cannot serialize the query,it will provide a better location of the error.

Arity errors

The server may return confusing error messages when the wrong numberof arguments is provided (Seerethinkdb/rethinkdb#2463 to track progress).Rethinkdbdash tries to make up for it by catching errors before sendingthe query to the server if possible.

Performance

The tree representation of the query is built step by step and stored which avoidrecomputing it if the query is re-run.

The code was partially optimized for v8, and is written in pure JavaScript which avoidserrors likeissue #2839

Run tests

Updatetest/config.js if your RethinkDB instance doesn't run on the default parameters.

Make sure you run a version of Node that supportsasync/await and run:

npm test

Longer tests for the pool:

mocha long_test/discovery.js -t 50000mocha long_test/static.js -t 50000

FAQ

  • Why rethinkdbdash?

    Rethinkdbdash was built as an experiment for promises and a connection pool. Itspurpose was to test new features and improve the official driver. Today,rethinkdbdash still tries to make the developer experience as pleasant as possible -like with the recent support for Node.js streams.

    Some features like promises have been back ported to the official driver, some likethe connection pool and streams are on their way.

  • Is it stable?

    Yes. Rethinkdbdash is used by quite many people. The driver is also used bythinky,and has been and is still being tested in the wild.

  • Does it work with io.js?

    All the tests pass with io.js so yes.

  • Is rethinkdbdash going to become the JavaScript official driver?

    Not (yet?), maybe :)

    Completely replacing the driver requires some work:

    • Integrate the driver in RethinkDB suite test.
    • Support HTTP connections.
    • Rollback some default like the coercion of cursors to arrays.
  • Can I contribute?

    Feel free to send a pull request. If you want to implement a new feature, please openan issue first, especially if it's a non backward compatible one.

Browserify

To build the browser version of rethinkdbdash, run:

node browserify.js

About

An advanced Node.js driver for RethinkDB with a connection pool, support for streams etc.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript100.0%

[8]ページ先頭

©2009-2025 Movatter.jp