After run command with db queries process is still work


#1

How to correct close command after run db queries?
I tried close db connections via await Database.close(), but command still working…


#2

Hey !

Have you tried to run Database.close() without await?


#3

Yes, it’s not work too


#4

Can you show us more code and also tell us which version of @adonisjs/lucid you are using?


#5

I’m try replay problem with clear code in command (only one query and close command) and it’s work correctly.

Command code

'use strict'

const ms = require('ms')
const _ = require('lodash')
const { Command } = require('@adonisjs/ace')
const Database = use('Database')
const JasperBeelineGate = use('App/Gates/JasperBeeline')

const Sim = use('App/Models/Sim')
const SimUsage = use('App/Models/SimUsage')

class JasperSync extends Command {
  static get signature () {
    return 'jasper:sync'
  }

  static get description () {
    return 'Ручная синхронизация симок (status, imei)'
  }

  async handle () {
    const startedAt = new Date()
    const self = this
    const jasper = new JasperBeelineGate()
    const answer = await jasper.getTerminals()

    if (!answer.iccids.length) {
      this.info('Iccids count is 0, exit')
      return
    }

    // Лимит в 50 позиций установлен из-за ограничений в запросах к Jasper
    const limit = 50

    // Начинаем выборку данных со смещения 0
    await fn(0)

    /**
     * Это рекурсия
     *
     * @param {Number} offset   Смешение в бд по записям в public.sims
     * @return {void}
     */
    async function fn (offset) {
      self.info(`offset ${offset} from ${answer.iccids.length}`)

      const iccids = answer.iccids.slice(offset, offset + limit)

      const detailed = await jasper.getTerminalsDetails(iccids)
      const terminals = detailed.terminals.terminal

      const sims = await Sim.query()
        .with('usage')
        .whereIn('iccid', iccids)
        .fetch()

      const simsHashes = _.transform(sims.rows, (result, sim) => {
        result[sim.iccid] = sim
      }, {})

      terminals.forEach(async (terminal) => {
        self.info(`iccid ${terminal.iccid}`)

        let sim

        if (terminal.iccid in simsHashes) {
          sim = simsHashes[terminal.iccid]
        } else {
          sim = new Sim()
          sim.iccid = terminal.iccid
        }

        sim.status = Sim.typeToNumber(terminal.status)
        sim.imei = Sim.imeiSvToImei(terminal.imei || null)
        sim.phone = terminal.attributes.msisdn
        await sim.save()

        let usage

        if (terminal.iccid in simsHashes && sim.$relations.usage) {
          usage = sim.$relations.usage
        } else {
          usage = new SimUsage()
          usage.sim_id = sim.id
        }

        usage.data = Number(terminal.monthToDateDataUsage)
        usage.sms = Number(terminal.monthToDateSMSUsage)
        usage.voice = Number(terminal.monthToDateVoiceUsage)

        await usage.save()
      })

      if (iccids.length === limit) {
        await fn(offset + limit)
      }
    }

    const duration = ms(new Date() - startedAt)
    this.completed('duration', duration)
    await Database.close()
  }
}

module.exports = JasperSync