Skip to content
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

Reloading driver causes failures on async functions #514

Closed
bdeterling opened this issue Feb 28, 2019 · 2 comments
Closed

Reloading driver causes failures on async functions #514

bdeterling opened this issue Feb 28, 2019 · 2 comments

Comments

@bdeterling
Copy link

bdeterling commented Feb 28, 2019

I'm not sure whether to classify this as a bug because I don't know what the official rule is on modules being reloaded. But I ran into this issue jestjs/jest#2826 when using Jest to test my database code so hopefully this will help anyone else that runs into it and perhaps the owners could implement a work-around or at least document it.

odbc.js overwrites the prototype of several of the native driver functions, such as prepare and execute. The section looks like this:

odbc.ODBCStatement.prototype._prepare = odbc.ODBCStatement.prototype.prepare;

Later, the prepare function itself is defined to call the original prepare, now called _prepare. That works fine, but when Jest uncaches and then reloads the module, those prototypes aren't reset to the native functions. So the second module load sets _prepare to the previously overwritten version and the native version is lost. When prepare tries to call _prepare, it is calling itself so it stops processing because the queue appears to be executing already. For execute, a stack overflow occurs because it just keeps calling itself. This happens whether I run the tests sequentially using --runInBand or the normal way. To reproduce, create two identical tests as follows:

import ibmdb from 'ibm_db';
const cs = ...; // connection string
test('Something works', (done) => {
  ibmdb.open(cs, (err, conn) => {
    conn.prepare('select count(*) from sysibm.sysdummy1', (err, stmt) => {
      // this is never run in the second test
      expect(stmt).toBeDefined();
      // rest of the code omitted because it never gets here,
      // but to fully test, do execute, fetch, etc
      done();
    });
  });
}

Running each test individually works fine. But run both tests in the same session and the second one will time out. Note: the done method is required or the tests will finish "successfully" before they hit the problem.

One suggested workaround was to use --no-cache --max-workers=n where n is 1 more then number of tests. That seems to help but would be inefficient with a lot of tests.

My workaround is to save off the original native functions and then export a function that can set them back at the end of the test. It looks something like this:

// in odbc.js, after module.exports = function (options) ...
var original_odbc = odbc;
var original_prepare = odbc.ODBCStatement.prototype.prepare;
// ... other functions
module.exports.resetLibrary = function() {
  original_odbc.ODBCStatement.prototype.prepare = original_prepare;
  // ...other functions
}

Then, in my test:

afterAll(() => {
  imbdb.resetLibrary();
});

Sorry for the long-winded issue, but hopefully this will save someone else the time that it took me to figure it out.

@coolweb
Copy link

coolweb commented Jun 28, 2019

Thanks a lot, I come across this issue too.

bimalkjha added a commit that referenced this issue Sep 6, 2022
 * fix: update binaries for windows and vscode (Bimal Jha)
 * fix: Reloading driver causes failures on async functions #514 (Bimal Jha)
 * fea: Convert the library to support Promises for all methods. #715 (Bimal Jha)
 * fea: add result.close API (Bimal Jha)
 * promisify describe related methods (Bimal Jha)
 * update mac binaries for vscode ibmdb/vscode-extension#50 (Bimal Jha)
 * test: update test files (Bimal Jha)
 * fix: Empty Strings in Batch inserts result in corrupt values being inserted #875 (Bimal Jha)
 * fea: Add support for Buffer() for insert and select for binary data. #702, #859, #860, #862, #864 (Bimal Jha)
 * fea: allow installation using specific version of clidriver (Bimal Jha)
@bimalkjha
Copy link
Member

@bdeterling @coolweb This issue is fixed in ibm_db@3.0.0 and it should work fine now. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants