Как освободить соединение с пулом из модели?

Я хочу прочитать большой файл JSON (это, если быть точным ), переберите его, проверьте, какие записи являются новыми, и при необходимости сохраните или обновите.

Делая это с парусами и парусами mysql я обнаружил, что весь процесс тормозит в первый раз и если я попытаюсь запустить его во второй раз, он в какой-то момент умрет. Мой сервер mysql, похоже, обрабатывает около 24 тыс. запросов и умирает.

Вот код, с помощью которого я заставил его работать, но он полностью игнорирует паруса, или паруса-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(), поскольку модель ватерлинии может использовать промисы.

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: я тоже пытался добавить тег паруса-mysql, но мне это не разрешено.


person tic2000    schedule 06.01.2015    source источник
comment
Почему бы просто не перезаписывать весь файл каждый раз? кажется быстрее, чем проверка измененных записей.   -  person Alex Hill    schedule 07.01.2015
comment
@AlexHill Я не хочу писать файл. Я хочу прочитать его и импортировать в базу данных. Затем, когда у меня есть записи, обновите базу данных, а не стирайте ее и снова импортируйте. Также пользователи могут изменять записи в базе данных, которые я хочу сравнить с файлом, и отправлять запросы на вытягивание в этот репозиторий с добавленной или исправленной информацией.   -  person tic2000    schedule 07.01.2015


Ответы (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])
})
person Esailija    schedule 07.01.2015
comment
Разве не возвращается в последнем то, что возвращается из всей цепочки внутри карты? - person tic2000; 07.01.2015
comment
Оператор return @tic2000 в javascript волшебным образом не возвращает что-то для других функций, а только функцию, в которой находится оператор return. - person Esailija; 07.01.2015
comment
ХОРОШО. Я добавил возврат. Но, к сожалению, это не отвечает на мой главный вопрос. Как я могу добиться этого в парусах, потому что conn.System.findOne({name: item.name}) не работает, и мне все еще нужно использовать conn.queryAsync('SELECT * FROM system WHERE name = "' + item.name + '"') - person tic2000; 07.01.2015
comment
@tic2000 вам нужно реализовать getSailsConnection - person Esailija; 07.01.2015
comment
Но как? Это был мой вопрос. Мой getSailsConnection был псевдокодом. Я не знаю, как подключиться к уже созданному пулу Sailes-MySQL и получить оттуда соединение. - person tic2000; 07.01.2015
comment
@ tic2000 есть ли документация по парусам mysql? - person Esailija; 07.01.2015
comment
@tic2000 Я думаю, вы можете просто запустить System.findOne без необходимости самостоятельно создавать соединение - person Esailija; 07.01.2015