X

The leading edge of scripting languages and Oracle Database brought to you by the Data Access Development team

Node.js node-oracledb 5.2 Dynamic Pool Reconfiguration

Christopher Jones
Senior Principal Product Manager

 

Release announcement: A new release of node-oracledb, the Node.js module for accessing Oracle Database, is available from npm.

Top features: dynamic reconfiguration of connection pools; better dead connection detection; support for a SODA metadata cache

Connection management is a key aspect of application design. Getting a connection needs to be quick; it needs to be reliable and self repairing if a there is a network outage; it needs to be used efficiently. So there's no surprise that the connection and connection pooling sections of the node-oracledb documentation are extensive. The new node-oracledb 5.2 release contains a number of enhancements and improvements, many around connections.

Highlights

  • Added a new pool function pool.reconfigure() to allow options such as the maximum pool size to be changed without pausing your application. This can be useful where the user load has changed (or will change), such as during a peak shopping period.

  • Formalized pool statistics with the addition of a pool creation attribute to start recording statistics enableStatistics, and with the functions pool.getStatistics() and pool.logStatistics(). The old _enableStats and _logStats() functionality are aliases for the enhancements.

  • Concurrent operations on a single connection are now queued in the JavaScript layer, which can help reduce thread usage for applications that are unable to do their own queuing.

    Oracle Database connections can only execute one operation at a time. This is a fundamental (i.e. insurmountable) behavior which needs understanding in the Node.js 'just do it in parallel' world. Previously constructs like Promise.all() on a single connection might have each work unit allocated to a thread, only one of which would be actually executing, while the others are blocked waiting for access to the connection. To avoid issues, we'd recommended keeping control in the application and avoiding Promise.all(). This is easy in custom code, but in generic frameworks isn't so feasible.

    Node-oracledb 5.2 now queues those 'parallel' requests in JavaScript and won't block multiple threads. This can give a smoother overall response time for the application since threads are available for other users when needed. A new errorOnConcurrentExecute property can be used during development to throw an error if concurrent operations are attempted on any single connection. This lets you check what's going on, for example you might have missed an await somewhere.

  • Improved dead connection detection handling. There were improvements to when and where node-oracledb checks connection validity. And there is a new error message. If an Oracle Database error indicates that a connection is no longer usable, the new error DPI-1080: connection was closed by ORA-%d is returned to the application. The "%d" will be the Oracle error that caused the connection to be closed. Using the connection after this will give the existing error message DPI-1010: not connected. The DPI-1080 message is also returned for callTimeout() errors that result in an unusable connection.

  • Users of the SODA document-store API will definitely want to upgrade. Several enhancements were made, notably the ability for pooled connections to use a metadata cache. This much requested change can significantly improve performance when repeatedly opening collections. Additionally there is support for caching the database version number in pooled connections with Oracle Client 19 and earlier (later Oracle Clients handle this caching internally) - the node-oracledb SODA implementation checks the DB version.

    A simple app that enables the metadata cache and does the following using Oracle Client 19 can reduce the required round-trips to one third of the previous number:

    conn = await pool.getConnection(); 
    soda = conn.getSodaDatabase();               // eliminated round-trip for reused pool connection
    coll = await soda.openCollection("mycoll");  // eliminated round-trip if mycoll metadata cached
    res = await coll.find().count();             // still calls the DB
    await conn.close();
    

    The reduction in round-trips has a measurable benefit, improving performance and scalability.

  • Enhanced getRows() to be able to return all rows in one call. If you are returning a REF CURSOR from a PL/SQL block and you know the number of rows is not huge, you can now do a single getRows() call instead of potentially having to loop and build up your own output array.

  • One bug fix I'll call out is for a crash that users were seeing with Worker Threads and/or test frameworks, mostly seen on Windows. This has now been squashed.

  • Users of GitHub source code should note that the default branch is now called main. GitHub will tell you what to do with your clones:

    git branch -m master main
    git fetch origin
    git branch -u origin/main main
    git remote set-head origin -a
    

See the CHANGELOG for all new features and bug fixes.

Installing or Upgrading node-oracledb

You can install or upgrade node-oracle by updating your package.json requirements:

"dependencies": {
   "oracledb": "^5.2"
},

We have tested with Node.js 12 and later, but the Node-API used is compatible with Node.js 10.16 if you haven't yet upgraded Node.js.

Resources

Node-oracledb installation instructions are here.

Node-oracledb documentation is here.

Node-oracledb change log is here.

Issues and questions about node-oracledb can be posted on GitHub or Slack (link to join Slack).

Follow us on Twitter or Facebook.

Finally, contributions to node-oracledb are more than welcome, see CONTRIBUTING.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.