adonisjs / core

AdonisJS is a TypeScript-first web framework for building web apps and API servers. It comes with support for testing, modern tooling, an ecosystem of official packages, and more.
https://adonisjs.com
MIT License
16.96k stars 638 forks source link

Ace commands never ends when queueing a job #2184

Closed Agilulfo1820 closed 3 years ago

Agilulfo1820 commented 3 years ago

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:

Possible hits:

thetutlage commented 3 years ago

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

thetutlage commented 3 years ago

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

Agilulfo1820 commented 3 years ago

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.

Agilulfo1820 commented 3 years ago

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
thetutlage commented 3 years ago

Couple of things

Agilulfo1820 commented 3 years ago

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.

thetutlage commented 3 years ago

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

Agilulfo1820 commented 3 years ago

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?

thetutlage commented 3 years ago

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

thetutlage commented 3 years ago

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

Agilulfo1820 commented 3 years ago

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

Agilulfo1820 commented 3 years ago

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.

Agilulfo1820 commented 3 years ago

@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.