Repository: oracle/node-oracledb

Issue #300: Document how to keep a pool connection healthy
Created: 2015-12-04T07:12:24Z
I am trying to use a pool as follows:

at application start, create a Promise "PoolP" for a pool
for every query:

use PoolP to get the pool and request a connection
with the connection, perform a query
always release the connection



This has the following issues:


After a suspend and resume the following day, I got the following error when trying to query:
Error: ORA-03113: end-of-file on communication channel
Process ID: 5051
Session ID: 69 Serial number: 140733193389459
at Error (native)

I suppose I should make a wrapper that intercepts this error and creates a new pool? Is this expected behavior, and are there other error conditions to handle?


if a connection is active, the application will keep running in the background when killed, holding open ports etc. I tried adding a SIGINT handler that terminates the pool but that just errors out if a connection is active


Thoughts? Should I just create a connection for every query and not bother with the pool?

Duplicate issue #460: Queries hang after long idle period (~hr), until service restarted
Created: 2016-06-17T20:00:11Z
I'm running an Express API who's only purpose is to execute queries using node-oracledb against our Oracle 11g DB.  Everything works perfectly, I'm even running ETL jobs hammering the API with requests and everything executes fine.
The ETL jobs all finish but then usually about an hour or so after that, any request to that API simply timeout.  Debugging it, it seems the queries just never return any results.  I restart the Node process (in my case bounce the docker container) and everything starts working again.  I'm using a resultSet (although I'm moving towards using the stream interface soon) and connection pool,
I'm wondering if this is related to this issue:
#395
Or is there something else I'm doing incorrectly here.
Here is my code where I setup my connection pool (I use a singleton of sorts...)
'use strict';
var oracledb = require('oracledb')
  , config = require('../config/config')
  , DB_ENV = process.env.NODE_ENV || 'staging'
  , connectObj = config[DB_ENV]
  ;

let instance = {};

module.exports = function OracleConnectionPool(cb) {
  var createInstance = function createInstance(ctx, done) {
    oracledb.createPool(connectObj, function (err, pool) {
      if (err) { return done(err); }
      ctx.pool = pool;
      done(null, ctx);
    })
  };


  if (!instance.pool) {
    createInstance(instance, function (err, ctx) {
      instance = ctx;
      cb(err, instance.pool);
    });
  } else {
    cb(null, instance.pool);
  }
};

And here is my code for executing my queries:
execute(cb) {
    let sqlToExecute = this.query
      , pool = this.pool
      , queryParams = this.queryInputParameters
      , queryResults = []
      ;

    function doRelease(connection) {
      connection.release(
        function(err)
        {
          if (err) { console.error(err.message); }
        });
    }

    function doClose(connection, resultSet) {
      resultSet.close(
        function(err)
        {
          if (err) { console.error(err.message); }
          doRelease(connection);
        });
    }

    checkCallback(cb);

    // connect to oracle db
    pool.getConnection(function(err, connection) {
      if (err) {
        return cb(new Error('Unable to establish connection'));
      }

      connection.execute(
        sqlToExecute,
        queryParams,
        { resultSet: true,
          outFormat: oracledb.OBJECT
        },
        function(err, result) {
          if (err) {
            doRelease(connection);
            return cb(err);
          }

          let fetchRowsFromRS = function (connection, resultSet, numRows) {
            resultSet.getRows( // get numRows rows
              numRows,
              function (err, rows)
              {
                if (err) {
                  doClose(connection, resultSet);
                  return cb(err);
                }

                if (rows.length > 0) {
                  rows.forEach((row) => queryResults.push(row));
                  if (rows.length == numRows) {
                    fetchRowsFromRS(connection, resultSet, numRows);
                  } else {
                    rows.forEach((row) => queryResults.push(row));
                    cb(null, queryResults);
                    doClose(connection, resultSet);
                    return;
                  }
                } else {
                  cb(null, queryResults);
                  doClose(connection, resultSet);
                  return;
                }
              });
          };

          fetchRowsFromRS(connection, result.resultSet, ROW_COUNT)

        });
    });
  }

(There is obviously some state in that code, I'm using ES6 classes, which I plan on refactoring out because they stink...)
I'm running everything in a docker container (https://hub.docker.com/r/collinestes/docker-node-oracle/).
Debian, Node 4.4
Any help is much appreciated, would love to get this API to a more stable point but right now I have to make sure I bounce it every hour or so.  Memory usage looks fine no memory leaks from what I can see.

Closing comment (2016-06-18T15:20:32Z): @ecowden I'm not convinced this is a dup of #300? Folks there were getting ORA-03113s, ORA-03135s, etc. You were reporting no errors, just hanging...