Skip to content

Rewrite native bindings #657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Nov 20, 2014
Merged

Rewrite native bindings #657

merged 31 commits into from
Nov 20, 2014

Conversation

brianc
Copy link
Owner

@brianc brianc commented Oct 11, 2014

The native bindings needed a full rewrite. They were complex, hard to maintain, and slow.

I rewrote the core of the native bindings from scratch into a module binding to the C libpq api called libpq. On top of this I've built a modernized, higher-level API to node-libpq called pg-native. Now pg consumes pg-native which in turn consumes libpq. This provides a much more modularized approach to things and one I plan to continue going forward.

why you should care:

  1. If you use the native bindings, the new implementation is >50% faster than the old native bindings in my crude benchmarks. Chances are the speed will be even better once I have time to optimize them.
  2. If you ever had an installation error compiling the native bindings for one reason or another and so opted to use pg.js instead. This problem will be going away by making the native bindings an optional add-on.
  3. If you like Piña Coladas... 🍍

before merging:

I will use some sort of npm beta tag for the new version of node-postgres for a while.

If you have non-mission-critical software I'd really love it if you could test out node-pg-native and help me shake out bugs over there.

I need to benchmark the new native bindings. Initial benchmarks show them to be >50% faster than the current version.

breaking changes:

  1. COPY TO / COPY FROM streaming support has been removed. This feature was buggy within node-postgres itself and has been replaced by the much more battle tested pg-copy-streams module. pg-native also provides native copy streams through libpq. I also plan on doing more experimentation with low-level copy operations within pg-pipe which allows me to use libpq to do some nice zero-copy buffer operations in C++.

  2. The native bindings will not support multiple statements returning different result sets in the same query. Only the last query in each command will return results. Doing 'pipelining' of multiple select statements is bad practice and not supported by the PostgreSQL backend when using prepared or parameterized queries. Multiple commands still work - and like today you will only have access to the results from the last command in the series. If you want to do something like this it wont work - use async & send two different queries:

    client.query('SELECT * FROM first_table; SELECT * FROM second_table')
  3. singleRowMode in libpq is not yet supported. It only works on PostgreSQL 9.3 anyways. If you want to stream a large batch of query results without exploding your memory space it is highly recommended you use pg-cursor or pg-query-stream. There is really no good way to support streaming rows from libpq...even singleRowMode has no concept of back pressure.

future plans:

The documentation is becoming a bit of a mess. I need to sit down and spend some time cleaning it up and modernizing it. Thanks for your patience when you wade through it now. 😄

I want to break out the JavaScript connection class into its own module. I want to build a new JavaScript higher level module to consume the connection in the same way node-pg-native consumes node-libpq.

I plan on making the native bindings an optional install instead of installing them by default. Much in the way node-redis uses hiredis if it is installed. This will cut down on a lot of support issues I have where someone does not have access to a compiler or PostgreSQL headers and so their installation fails even though they have a perfectly usable, production-grade client installed in pure node.js.

Long term I see node-postgres being sort of a meta-package that glues together a bunch of smaller modules and provides the API it always has -- warts and all -- for maximum backwards compatibility. I know how annoying it is to have a boring, core piece of your infrastructure modules breaking compatibility for less than critical reasons & leaving you faced with the choice of either a painful, error-prone upgrade to get new functionality, or leaving you stuck on an old version for a long time. I have and will always strive to keep breaking changes to an absolute minimum. The smaller modules can be used when only some of the features are required, and their APIs can be simpler to learn and easier to evolve.

Fixes a case where you connect & immediatley disconnect and _sometimes_ your notification subscription starts the reader on the libpq instance after the libpq instance is disconnected.  This segfaults the app.
brianc added a commit that referenced this pull request Nov 20, 2014
Rewrite native bindings
@brianc brianc merged commit 13ba76b into master Nov 20, 2014
@brianc brianc deleted the libpq branch November 20, 2014 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant