【问题标题】:How do I release a pool connection from a model?如何从模型中释放池连接?
【发布时间】:2015-01-06 23:21:22
【问题描述】:

我想读取一个大的 JSON 文件(准确地说是this),对其进行迭代,检查哪些是新条目并根据需要保存或更新。

用sails 和sails mysql 做这个我发现整个过程第一次变慢了,如果我第二次尝试运行它,它会在某个时候死掉。我的 mysql 服务器似乎处理了大约 24k 的请求并死掉了。

这是我让它工作的代码,但它完全忽略了sails或sails-mysql,我直接使用mysql来实现这一点。

这是工作代码:

var path = require('path')
var Promise = require('bluebird')
var fs = Promise.promisifyAll(require('fs'))
var rootPath = process.cwd()
var filePath = path.join(rootPath, 'assets/systems.json')
var mysql = require("mysql");
Promise.promisifyAll(mysql);
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
var pool  = mysql.createPool({
  connectionLimit: 10,
  host: 'localhost',
  user: 'user',
  password: 'pass',
  database: 'db'
});

function getSqlConnection() {
  return pool.getConnectionAsync().disposer(function(connection) {
    connection.release();
  });
}

fs.readFileAsync(filePath, 'utf8').then(JSON.parse).then(function(systems) {
  total = systems.length
  return systems
})
.map(function(item, index, value) {
  Promise.using(getSqlConnection(), function (conn) {
    return conn.queryAsync('SELECT * FROM system WHERE name = "' + item.name + '"')
  })
  .then(function(have_system) {
    // do something with the info
    return the_result_of_doing_something
  })
  .caught(function(err) {
    console.log(err)
  })
}, {concurency: 5})
.caught(SyntaxError, function(e) {
  console.log("Invalid JSON in file " + e.fileName + ": " + e.message);
})
.lastly(function() {
  broadcast(["All DONE!!!", updated_systems, new_systems, current])
})

如何在不需要 mysql 并创建自己的连接的情况下实现这一点?所以这个:

function getSqlConnection() {
  return pool.getConnectionAsync().disposer(function(connection) {
    connection.release();
  });
}

Promise.using(getSqlConnection(), function (conn) {
  return conn.queryAsync('SELECT * FROM system WHERE name = "' + item.name + '"')
})

会变成这样:

function getSailsConnection() {
  return sails.pool.getConnectionAsync().disposer(function(connection) {
    connection.release();
  });
}

Promise.using(getSailsConnection(), function (conn) {
  return conn.System.findOne({name: item.name})
})

如果我可以正确释放,我什至不必使用 Promise.using(),因为水线模型可以使用 Promise。

System.findOne({name: item.name}).then(function(have_system) {
  // do something
  System.releaseConection() // or some other API call to achieve this
})
.caught(function(err) {
  System.releaseConection() // or some other API call to achieve this
})

PS:我也尝试添加一个sails-mysql标签,但我不被允许。

【问题讨论】:

  • 为什么不每次都覆盖整个文件呢?似乎比检查更改的条目更快。
  • @AlexHill 我不想写文件。我想从中读取并将其导入数据库。然后当我确实有条目时更新数据库而不是擦除它并再次导入。用户还可以修改数据库中我想与文件进行比较的条目,并使用添加或更正的信息向该存储库提交拉取请求。

标签: mysql node.js sails.js waterline bluebird


【解决方案1】:

你没有从 .map 回调返回任何承诺,所以不仅承诺会提前实现,concurrency 也不会做任何事情。

您也可以为整个事情使用单个连接:

using(getSailsConnection(),
      fs.readFileAsync(filePath, 'utf8').then(JSON.parse), function(conn, systems) {
    return systems.map(function(item) {
        return conn.System.findOne({name: item.name});
          .then(function() {

          })
    }, {concurrency: 5});
})
.lastly(function() {
  broadcast(["All DONE!!!", updated_systems, new_systems, current])
})

【讨论】:

  • 最后返回的不就是map里面的整个链返回什么吗?
  • @tic2000 javascript 中的 return 语句不会神奇地为其他函数返回一些东西,只有 return 语句所在的函数
  • 好的。我添加了一个回报。但不幸的是,这并不能回答我的主要问题。我怎样才能在风帆中实现这一点,因为conn.System.findOne({name: item.name}) 不起作用,我仍然必须使用conn.queryAsync('SELECT * FROM system WHERE name = "' + item.name + '"')
  • @tic2000 你需要实现 getSailsConnection
  • 但是怎么做呢?那是我的问题。我的 getSailsConnection 是伪代码。我不知道如何钩入已创建的池sails-mysql 并从那里获取连接。
猜你喜欢
  • 1970-01-01
  • 2014-05-07
  • 2014-08-06
  • 2013-05-01
  • 2016-10-24
  • 2012-04-22
  • 2015-12-04
  • 2017-08-12
  • 1970-01-01
相关资源
最近更新 更多