Core: Ace commands never ends when queueing a job

Created on 28 Jan 2021  路  13Comments  路  Source: adonisjs/core

Package version

"adonis-version": "4.1.0",

Node.js and npm version

node v12.18.2
npm 6.14.10

Sample Code (to reproduce the issue)

  1. Add a job queue library (ex Adonis Bull)
  2. Create a job with a console log in the handle method
  3. Create an ace command that queues the job inside the handle method

Result: Job will be executed but the command won't end (close it with CTRL+C)

Expected result: job is triggered and command closes correctly.

What I tried:

  • Manually closing connection to the db and redis both inside the command and the job.
  • I tried using different queue packages (adonis-queue, adonis-queue-pro and adonis bull); with adonis-queue and adonis-queue-pro I couldn't even stop it with CTRL+C and ALL commands were affected. Now with bulls only commands with jobs are affected and I can stop the command with CTRL+C.

Possible hits:

  • The console log output don't come from the command output terminal but from the API watcher (I'm using docker containers so the output is coming out from the API container). But this should be the right way (because it's the output of a job).
Question

All 13 comments

Can you share the code which tries to close connection with the Redis and the database?

Also, in future, I suggest creating a discussion thread and not an issue (until it has been confirmed as an issue). Same for this https://github.com/adonisjs/core/issues/2185

Also, in future, I suggest creating a discussion thread and not an issue (until it has been confirmed as an issue). Same for this #2185

Sorry, you are right. I was dubious about it too.

Can you share the code which tries to close connection with the Redis and the database?

'use strict'

const {Command} = require('@adonisjs/ace')
const Bull = use('Rocketseat/Bull')
const ImportTagsJob = use('App/Jobs/ImportTagsJob')
const Database = use('Database')
const Redis = use('Redis')

class ImportTags extends Command {
    static get signature() {
        return 'process:imported-tags'
    }

    static get description() {
        return 'Import nfc and rfid tags from S3'
    }

    async handle() {
        Bull.add(ImportTagsJob.key)

        Database.close()
        await Redis.quit()
    }
}

module.exports = ImportTags

Couple of things

  • I have never uses Bull myself, so not sure about its internals. Does it use the Redis provider of AdonisJS?
  • And the database close call should be awaited too.

Couple of things

  • I have never uses Bull myself, so not sure about its internals. Does it use the Redis provider of AdonisJS?

Yes, this is the config/bull.js:

"use strict";

const Env = use("Env");

module.exports = {
  // redis connection
  connection: Env.get("BULL_CONNECTION", "bull"),
  bull: {
    redis: {
      host: "127.0.0.1",
      port: 6379,
      password: null,
      db: 0,
      keyPrefix: ""
    }
  },
  remote: "redis://redis.example.com?password=correcthorsebatterystaple"
};
  • And the database close call should be awaited too.

Tried with await Database.close() with no results.

May I know how this config indicates that it is using the AdonisJS Redis provider?

Sorry, you are right, I'm specifying the redis configurations myself, so maybe Bull opens a different connection that I do not control?
Are there ways to know with redis connections are open and maybe close it?

Looking at their source code. They are not using the AdonisJS Redis provider, instead they pass the config directly to bull, which indeed creates and manages it own Redis instance.

You will have to check the Bull or AdonisJS/bull API to see how you can close those connections

The simplest way will be to call process.exit(0) within the command handle method to kill the process.

I also opened an issue on their side: https://github.com/Rocketseat/adonis-bull/issues/62

The simplest way will be to call process.exit(0) within the command handle method to kill the process.

Yes, this way it works:

'use strict'

const {Command} = require('@adonisjs/ace')
const Bull = use('Rocketseat/Bull')
const ImportTagsJob = use('App/Jobs/ImportTagsJob')

class ImportTags extends Command {
    static get signature() {
        return 'process:imported-tags'
    }

    static get description() {
        return 'Import nfc and rfid tags from S3'
    }

    async handle() {
        Bull.add(ImportTagsJob.key)
        setTimeout(function() {
            process.exit(0)
        }, 2000);
    }
}

module.exports = ImportTags

Not sure if it could cause some other unexpected problem.

@thetutlage I will use this solution, thank you for your help. I think you can close the issue and lets see if the guy over the Bull community can implement a more elegant way of doing it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

codingphasedotcom picture codingphasedotcom  路  3Comments

ghost picture ghost  路  3Comments

PC-HUB picture PC-HUB  路  4Comments

Extarys picture Extarys  路  4Comments

themodernpk picture themodernpk  路  3Comments