Mysql PoolПравильно закрыть соединения после запроса

Привет!
Опять я))
Имею такой код:
index.js

const rp = require('request-promise');
require('dotenv').config()
const TelegramApi = require('node-telegram-bot-api')
const bot = new TelegramApi(process.env.BOT_TOKEN, {polling: true})
var db = require('./my_sql_connect.js');
const cron = require("node-cron");
const propotkl=5;
bot.setMyCommands([
  {command: '/add', description: 'Add node: /add xxx.xxx.xxx.xxx:9000'},
  {command: '/delete', description: 'Delete node: /delete xxx.xxx.xxx.xxx:9000'}, 
  {command: '/notif', description: 'show logs'},
  {command: '/notifoff', description: 'hide logs'},  
  {command: '/my', description: 'your nodes'}
])

 const start = () => {
    bot.on('message', async msg => {
      const text = msg.text;     
      /* if(msg.from.id != chatId){
        return bot.sendMessage(msg.from.id, 'создайте своего бота, в инструкции же написано!');
      } */
      //console.log(msg)
      if(text === '/start'){
        return bot.sendMessage(msg.from.id, `Welcome to Sui testnet checker bot`)
      }

      if(/^\/add\s([0-9]{1,3}[\.]){3}[0-9]{1,3}[\:]{1}[0-9]{4,5}$/.test(text)){
        var ip=text.replace("/add ", "").trim();          
            const sql = `INSERT INTO userip(userid,ipu) VALUES (?, ?);`
            db.query(sql, [msg.from.id,ip],function(err, resp) {
              if(err) {
                bot.sendMessage(msg.from.id,'failed to add data | не удалось добавить данные')             
                return console.log(err);
              }
              bot.sendMessage(msg.from.id,`ip ${ip} added to user ${msg.from.id}`)
              console.log('Inserted ')
            })
        return
      }

      if(text === '/my'){
        console.log("нажат my")  
          console.log("базу прошли")
          
            const sql = `SELECT ipu FROM userip WHERE userid=?`;
            db.query(sql, [msg.from.id],function(err, resp) {
              if(err) {
                bot.sendMessage(msg.from.id,'не удалось достать данные | failed to retrieve data')             
                return console.log(err);
              }
              //bot.sendMessage(msg.from.id,`ip ${ip} добавлен к юзеру ${msg.from.id}`)
              if(resp && resp!=''){
                resp.map((ip)=>{                  
                  bot.sendMessage(msg.from.id,`Ваши ip ${ip.ipu}`)
                })
              }else{
                bot.sendMessage(msg.from.id,`You haven't added an ip yet | Вы еще не добавили ip`)
              }              
            })
        return
      }

      if(text === '/notif'){  
            let tmpsql=`UPDATE userip SET worked=0 WHERE userid=?`;
            db.query(tmpsql, [msg.from.id],function(err, resp) {
              if(err) {                          
              return console.log(err);
              }
              bot.sendMessage(msg.from.id, `Sending logs is enabled`)
            })
      }

      if(text === '/notifoff'){
            let tmpsql=`UPDATE userip SET worked=1 WHERE userid=?`;
            db.query(tmpsql, [msg.from.id],function(err, resp) {
              if(err) {                          
              return console.log(err);
              }
              bot.sendMessage(msg.from.id, `Sending logs is disabled`)
            })
        return
      }

      if(/^\/delete\s([0-9]{1,3}[\.]){3}[0-9]{1,3}[\:]{1}[0-9]{4,5}$/.test(text)){
        var ip=text.replace("/delete ", "").trim();
            const sql = `DELETE FROM userip WHERE ipu=? AND userid=?;`
            db.query(sql, [ip,msg.from.id],function(err, resp) {
              if(err) {
                bot.sendMessage(msg.from.id,'failed to delete ip | не удалось удалить ip')             
                return console.log(err);
              }
              if(resp.affectedRows>0) {
                bot.sendMessage(msg.from.id,`ip ${ip} deleted`)
              }else{
                bot.sendMessage(msg.from.id,`ip ${ip} not found`)
              }
              console.log('Deleted:')
            })
        return
      }

      return bot.sendMessage(msg.from.id, `Unknown command`)      
    })
  }
  
  start()
async function curl(val){
  const ip = `http://${val}`
  var options = { 
    method: "POST", 
    //uri: "https://fullnode.testnet.sui.io:443", 
    uri: ip,
    body: { "jsonrpc":"2.0", "method":"sui_getTotalTransactionNumber","id":1},
    headers:{"Content-Type":"application/json"},
    json: true
    }
    try{
      let tmp = await rp(options)
      console.log(ip," :ответил", tmp.result)
      return(tmp)
    }catch{
      console.log(ip," :неотвечает")
    }
}
  cron.schedule('*/1 * * * * *', async () => { 
    let bddata;
        console.log("зашли читать БД");
        const sql = `SELECT * FROM userip`;
        db.query(sql, '',function(err, resp) {
          if(err) {
            //bot.sendMessage(msg.from.id,'не удалось добавить данные')             
            return console.log(err);
          }
          bddata =resp
          //console.log(bddata)          
          if(bddata && bddata!=''){
                bddata.map(async (val)=>{
                 console.log("получили ip", val.ipu)
                 let tmp = await curl(val.ipu);
               
                })
          }else{
           // console.log(`База пуста`)
          } 
          
        })
    //console.log("bddata")
  })   

my_sql_connect.js

const mysql = require("mysql2");
const pool = mysql.createPool({
    connectionLimit: 2,    
    host: "localhost",
    user: "sui_user",
    database: "sui_bot",
    password: "Tarab@739739739"
})

pool.getConnection((error) => {
    if(error){
        return console.log("Ошибка подключения");
    }else{
        return console.log("Подключение установлено!");
    }
})
module.exports = pool

Это телеграм бот. Функция start() вызывается всякий раз, когда пользователь нажмет на кнопку в телеге. Например, добавить айпи, удалить айпи, вывести мои айпи.
А вторая часть с кроном, непрерывно каждую секунду обращается к базе, вытаскивает все айпи и проверяет приложение сервера на онлайн через курл.
Как в пуле организовать закрытие к базе. Если в start() например в /my добавлю db.close(), то закроется все соединение в том числе в кроне.
Хотелось бы после нажатия открыть соединение в /my потом зарыть только это соединение, а часть с кроном, чтобы использовало другое соединение и не знала об открытии, закрытии в других функциях.
Что, если добавить в части с кроном создать другого пользователя базы и работать с ним?
Прочел несколько статей про pool, там пишут закрыть текущее соединение командой db.release(). Но она выдает ошибку " db.releace is not a function"

Нужно в самом start как и в кроне получать соединение, делать операцию и закрывать соединение.

Примерный код:

const start = () => {
   bot.on('message', () => {
      pool.getConnection((err, connection) => {
         // connection operations
         connection.query(/* ... */);
         pool.releaseConnection(connection)
      })
   })
}

Есть вариант АПИ mysql2 когда ты операцию в пулле соединений, и по завершению операции соединение само освобождается. Пример из документации:

// For pool initialization, see above
pool.query("SELECT field FROM atable", function(err, rows, fields) {
   // Connection is automatically released when query resolves
})

Спасибо большое Дмитрий!
У меня mysql2

const mysql = require("mysql2");
const pool = mysql.createPool({
    connectionLimit: 2,    
    host: "localhost",
    user: "sui_user",
    database: "sui_bot",
    password: "Tarab@739739739"
})

pool.getConnection((error) => {
    if(error){
        return console.log("Ошибка подключения");
    }else{
        return console.log("Подключение установлено!");
    }
})
module.exports = pool

Тогда что не нужно закрывать?

pool.getConnection нужно закрывать в коллбеке. А вот pool.query и pool.execute не нужно.

Спасибо Дмитрий! А какой командой закрывать?
Если сделаю db.end() все же соединения закроются
так чтоли?
pool.releaseConnection(connection)

Если ставлю так:


то выходит такая ошибка

 if (!connection._pool) {
                    ^

TypeError: Cannot read properties of undefined (reading '_pool')
    at Pool.releaseConnection (/root/suibots/node_modules/mysql2/lib/pool.js:82:21)
    at TelegramBot.<anonymous> (/root/suibots/index.js:63:16)
    at TelegramBot.emit (/root/suibots/node_modules/eventemitter3/index.js:182:35)
    at TelegramBot.processUpdate (/root/suibots/node_modules/node-telegram-bot-api/src/telegram.js:680:12)
    at /root/suibots/node_modules/node-telegram-bot-api/src/telegramPolling.js:110:22
    at Array.forEach (<anonymous>)
    at /root/suibots/node_modules/node-telegram-bot-api/src/telegramPolling.js:106:17
    at tryCatcher (/root/suibots/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/root/suibots/node_modules/bluebird/js/release/promise.js:547:31)
    at Promise._settlePromise (/root/suibots/node_modules/bluebird/js/release/promise.js:604:18)
    at Promise._settlePromise0 (/root/suibots/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (/root/suibots/node_modules/bluebird/js/release/promise.js:729:18)
    at _drainQueueStep (/root/suibots/node_modules/bluebird/js/release/async.js:93:12)
    at _drainQueue (/root/suibots/node_modules/bluebird/js/release/async.js:86:9)
    at Async._drainQueues (/root/suibots/node_modules/bluebird/js/release/async.js:102:5)
    at Immediate.Async.drainQueues (/root/suibots/node_modules/bluebird/js/release/async.js:15:14)
    at processImmediate (node:internal/timers:466:21)

Где воткнуть закрытие?

Если добавить в my_sql_connect.js так

const mysql = require("mysql2");
const pool = mysql.createPool({
    connectionLimit: 200,    
    host: "localhost",
    user: "sui_user",
    database: "sui_bot",
    password: "Tarab@739739739"
})

pool.getConnection((error) => {
    if(error){
        return console.log("Ошибка подключения");
    }else{
        return console.log("Подключение установлено!");
    }
})
pool.releaseConnection()
module.exports = pool

то тоже такая же ошибка

pool.releaseConnection() должен быть внутри коллбека getConnecetion(() => { ... })

В этом коде вообще не видно внутри ли .getConnection выполняется код или нет. Не понятно что в переменной db. В ней пулл соединений или это объект базы. Если это объект базы, то с ним не получится работать как с пуллом.

Кинь полный код чтобы было понятно к чему какие переменные относятся, тогда смогу подсказать

Спасибо Дмитрий!
index такой

const rp = require('request-promise');
require('dotenv').config()
const TelegramApi = require('node-telegram-bot-api')
const bot = new TelegramApi(process.env.BOT_TOKEN, {polling: true})
var db = require('./my_sql_connect.js');
const fs = require('fs')
bot.setMyCommands([
  {command: '/start', description: 'start'},
  {command: '/check', description: 'check'},
  {command: '/checkrpc', description: 'checkrpc'},
  {command: '/add', description: 'Add node: /add xxx.xxx.xxx.xxx:9000'},
  {command: '/delete', description: 'Delete node: /delete xxx.xxx.xxx.xxx:9000'},
  {command: '/my', description: 'your nodes'}
])

 const start = () => {
    bot.on('message', async msg => {
      const text = msg.text;     
      /* if(msg.from.id != chatId){
        return bot.sendMessage(msg.from.id, 'создайте своего бота, в инструкции же написано!');
      } */
      //console.log(msg)
      if(text === '/start'){
        let bottext = "\nДобавьте свои ip по команде"
        bottext += "\n/add ip:port"
        bottext += "\nПример: /add 185.209.31.45:9000"
        bottext += "\nПроверьте синхронизацию командой /check"
        bottext += "\nИ сравните с РПЦ /checkrpc"
        return bot.sendMessage(msg.from.id, `Welcome to Sui testnet checker bot ${bottext}`)
      }

      if(/^\/add\s([0-9]{1,3}[\.]){3}[0-9]{1,3}[\:]{1}[0-9]{4,5}$/.test(text)){
        var ip=text.replace("/add ", "").trim();          
            const sql = `INSERT INTO userip(userid,ipu) VALUES (?, ?);`
            db.query(sql, [msg.from.id,ip],function(err, resp) {
              if(err) {
                bot.sendMessage(msg.from.id,'failed to add data | не удалось добавить данные')             
                return console.log(err);
              }
              bot.sendMessage(msg.from.id,`ip ${ip} added to user ${msg.from.id}`)
              //console.log('Inserted ')
            })
        return
      }

      if(text === '/my'){
        //console.log("нажат my") 
            const sql = `SELECT ipu FROM userip WHERE userid=?`;
            db.query(sql, [msg.from.id],function(err, resp) {
              if(err) {
                bot.sendMessage(msg.from.id,'не удалось достать данные | failed to retrieve data')             
                return console.log(err);
              }
              //bot.sendMessage(msg.from.id,`ip ${ip} добавлен к юзеру ${msg.from.id}`)
              if(resp && resp!=''){
                resp.map((ip)=>{                  
                  bot.sendMessage(msg.from.id,`Ваши ip ${ip.ipu}`)
                })
              }else{
                bot.sendMessage(msg.from.id,`You haven't added an ip yet | Вы еще не добавили ip`)
              }
            })
            
        return
      }
      if(text === '/check'){
        const sql = `SELECT ipu FROM userip WHERE userid=?`;
        db.query(sql, [msg.from.id],function(err, resp) {
          if(err) {
            bot.sendMessage(msg.from.id,'не удалось достать данные | failed to retrieve data')             
            return console.log(err);
          }
          if(resp && resp!=''){
            resp.map(async (ip)=>{              
                //console.log("получили ip", ip.ipu)
                let otvet = await curl(ip.ipu);
                //console.log("ответ получен")
              //console.log("otdet: ",otvet)
              if(otvet && otvet!=''){
                bot.sendMessage(msg.from.id, `${ip.ipu} :  ${otvet}`)
              }else{
                bot.sendMessage(msg.from.id,`${ip.ipu} :  не ответил`)
              }
              
            })
          }else{
            bot.sendMessage(msg.from.id,`You haven't added an ip yet | Вы еще не добавили ip`)
          }           
        })            
    return
  }
  if(text === '/checkrpc'){
    let fileContent =''
    try{
      fileContent = fs.readFileSync("rpc.txt", "utf8");
    }
    catch (error) {
      return false
    }
    //console.log(fileContent)
      let rpcarr=fileContent.split(',');
      //console.log(rpcarr)      
      if(rpcarr && rpcarr!=''){
        rpcarr.map(async (ip)=>{              
           // console.log("получили ip", ip)
            let otvet = await curl(ip,false);
           // console.log("ответ получен")
        //  console.log("otdet: ",otvet)
          if(otvet && otvet!=''){
            bot.sendMessage(msg.from.id, `${ip} :  ${otvet}`)
          }else{
            bot.sendMessage(msg.from.id,`${ip} :  не ответил`)
          }
          
        })
      }else{
        bot.sendMessage(msg.from.id,`RPC пуст`)
      }
                    
            
return
}

      if(/^\/delete\s([0-9]{1,3}[\.]){3}[0-9]{1,3}[\:]{1}[0-9]{4,5}$/.test(text)){
        var ip=text.replace("/delete ", "").trim();
            const sql = `DELETE FROM userip WHERE ipu=? AND userid=?;`
            db.query(sql, [ip,msg.from.id],function(err, resp) {
              if(err) {
                bot.sendMessage(msg.from.id,'failed to delete ip | не удалось удалить ip')             
                return console.log(err);
              }
              if(resp.affectedRows>0) {
                bot.sendMessage(msg.from.id,`ip ${ip} deleted`)
              }else{
                bot.sendMessage(msg.from.id,`ip ${ip} not found`)
              }
              //console.log('Deleted:')
            })
        return
      }

      return bot.sendMessage(msg.from.id, `Unknown command`)      
    })
  }
  
  start()
async function curl(val,http=true){
  var ip=""
  if(http){
    ip = `http://${val}`
  }else{
    ip = val
  }
  
  var options = { 
    method: "POST", 
    //uri: "https://fullnode.testnet.sui.io:443", 
    uri: ip,
    body: { "jsonrpc":"2.0", "method":"sui_getTotalTransactionNumber","id":1},
    headers:{"Content-Type":"application/json"},
    timeout: 5000,
    json: true
    }
    try{
     // console.log("ждем ответа от: ", ip)
      let tmp = await rp(options)
     // console.log(ip," :ответил", tmp.result)
      return(tmp.result)
    }catch{
      //console.log(ip," :неотвечает")
    }
}
  
 
    
    
  

my_sql_connect.js

const mysql = require("mysql2");
const pool = mysql.createPool({
    connectionLimit: 200,    
    host: "localhost",
    user: "sui_user",
    database: "sui_bot",
    password: "Tarab@739739739"
})

pool.getConnection((error) => {
    if(error){
        return console.log("Ошибка подключения");
    }else{
        return console.log("Подключение установлено!");
    }
})

module.exports = pool
    

Хочу во всех if(/команда), там где соединение сразу после обработки закрыть

Код рабоч так как он выглядит. db.query закрывать не надо, в документации mysql2 - npm вот тут описано:

1 лайк

Спасибо!!!