Objection.js: Need to explicit destroy knex in order to stop the script

Created on 4 Oct 2017  路  17Comments  路  Source: Vincit/objection.js

Hi, I initialize Model this way:

const Knex = require('knex');
const Model = require('objection').Model;
const knex = new Knex({
  client: 'pg',
  pool: { min: 1, max: 10 },
  connection: {},
  searchPath: 'knex,public',
});
Model.knex(knex);

The problem I have is when I run tests with mocha, mocha never ends until I run:

knex.destroy();

And even if I run it, mocha keep waiting for extra 5-10 seconds, and after actually ends.
Which makes me believe, that Objection or knex still have some process running to keep pool connections alive.

Any suggestions how could I cut this "waiting" time in mocha?

Most helpful comment

add idleTimeoutMillis: 500 too if you want to use knex in jest

All 17 comments

Hi!

I use after(() => knex.destroy()) and that's enough to let the process die immediately. Neither objection nor knex start any processes.

Have you tried setting the minimum pool size to zero?

@Kostanos As food for thought, in my own mocha tests, I leverage the after hook in the mocha config to kill my process. E.g.

...
// After hook
after(function(done) {
  return doTeardownStuff()
    .catch(err => {
      console.log(err);
      return Promise.resolve();
    })
    .then(() => {
      // Kill the process after some time passes, because I know that I am done.
      setTimeout(function() {process.exit();}, 2000);
    });
});
...

It's a little bit "hacky" but it works fine and I think is safe enough for my scenario.

I have never had to kill the process, nor have I ever had problems with mocha tests not finishing. I think there is something "wrong" with your setups. Check out objection's tests. They have no such problem.

Just tried with min=0, same result :(

Thank you for killing suggestion, it works, at least now test doesn't consume extra actually >20 seconds, as I see in pipeline.

BTW. the draining of knex with DEBUG=*

  knex:pool INFO pool postgresql:pg:client0 - draining +7ms
  knex:pool INFO pool postgresql:pg:client0 - force destroying all objects +0ms

I'm checking other possible scenarios, I have pg-restify server, which I also put down with:

this.restify.close();

But the issue only happens when I run test that uses ModelBase I showed above.

In tests where ModelBase is not used, the script exists fast.

I'm pretty sure this has nothing to do with objection, but just to make sure, could you create a small standalone project that reproduces this? I'm not able to reproduce this.

Maybe you have transactions that are never committed or rolled back? Those keep a connection alive.

Will try later about small project.
It is more complex here, for sure it may be provoked by some other dependency, even the same pg-restify + objection may have conflicts, as both of them open connections on their own.

No pending transactions for sure, checked it.

The reason why I pointed to objection+knex, is because if I don't destroy knex with knex.destroy(), the test never ends at all, and with DEBUG=* I see knex keeps pinging connection in pool.

Anyway, for now I'm ok with process.exit, will go forward with next tasks.

If you prefer, we can close this task until I have more data to reproduce it.

Thank you for your time and help!

This can easily be an issue in knex. Objection doesn't start queries or do anything funky without the user explicitly telling it. I'll close this now, but I'd like to know what caused this if you get to the bottom of this.

For me explicitly setting pool.min = 0 and knex.destroy() in jasmine.onComplete did the trick. My issue was similar with yours: Testing process was not exiting. What's odd is that pool.min should be 0 by default but I still needed to explicitly set it in my knexfile. Any thoughts?

@tmaxim-gpsw No idea. I have never had that issue. Knex github or gitter is probably a better place to get the answer for this.

I'm not sure if related, but default behaviour changed in mocha https://github.com/mochajs/mocha/blob/master/CHANGELOG.md#default-behavior

That it does not force exit after tests has been ran, so I suppose it will wait until generic-pool evicts idle connections before exitting...

Supply the --exit flag to revert to pre-v4.0.0 behavior

I would go for explicitly destroying knex after tests has been complete.

I would go for explicitly destroying knex after tests has been complete.

@elhigu The issue seems to be that knex.destroy() isn't enough.

Uh right... I missed that. knex.destroy() waits nowadays that connections are closed gracefully... so I would expect that testcode has something fishy going on in this case... maybe an open transaction or something like that.

Seeing the same problem. It was fixed by using pool: {min: 0}. I'll add knex.destroy() just in case.

add idleTimeoutMillis: 500 too if you want to use knex in jest

I've added idleTimeoutMillis, but still have the issue.
This is my knex/objection initialization file:

const info = require('debug')('ws:info:db');

const Knex = require('knex');
const Model = require('objection').Model;

info('Connecting..');
const knex = Knex({
  client: 'pg',
  pool: { min: 0, max: 10, idleTimeoutMillis: 500, },
  connection: {},
  searchPath: 'knex,public',
  // debug: true,
});

Model.knex(knex);

module.exports = Model;

and here how I close it:

const ModelBase = require('./lib/models/ModelBase');

      ModelBase.knex().destroy()
      .then(() => {
        // TODO:  never enters here on tests :(
        debug('Knex closed');
        if (this.wsServer){
          debug('Closing WS Server');
          this.wsServer.close(() => {
            this.server.close(resolve);
          });
        } else resolve();
      });

BTW. it only happens if I run at least one query. if I don't run any queries, no timeout on tests (the connections closes without issues)

I still have the issue with idleTimeoutMillis: 500

Was this page helpful?
0 / 5 - 0 ratings