node + mssql
Всем здравия! Господа, может кто сталкивался, вот такое дело:
имеем серверную часть node. в ней объект работы с mssql сделан в виде объекта и объявлен как константа. другими словами один объект открывает connect и держит его для любого подключения. если коннект обрывается он опять его коннектит. т.е. коннект всегда актуален. К серверу подключаются клиенты. Подключился один клиент, выдал серверу команду. вместе с сервером клиент начинает отрабатывать некий цикл задач. все вроде бы нормально. Подключился второй и так далее. Но выявилось что, как только клиент за одно обращение передает команду которая требует нескольких операций с mssql за раз на сервере - сервер делает первую и дальше выдает ошибку, что нужно сначала дождаться логина и только потом выполнять запрос. Фигня какая то. Причем у него статус LoginIn находится в состоянии true. Возникает ощущение что на каждый запрос нужно делать коннект! Фигня какая то. С другой стороны несколько клиентов могут полчаса долбить его и все нормально. Первое обращение с несколькими запросами (выполняются на сервере ПОСЛЕДОВАТЕЛЬНО) на одном клиентском соединении - и пипец. Есть идеи? |
неужели нужно постоянно долбить mssql коннектами? долго и неэффективно
|
Сумбурное объяснение но ты уверен что у тебя достаточно лицензий куплено чтобы держать больше пяти одновременных подключений?
|
Могу еще перегрузить модем, может поможет?
|
ответ есть вот здесь.
https://github.com/tediousjs/tedious/issues/458 походу так и есть...... на каждые request -> connect. хотя бред, не может такого быть.... |
во как пишут...
you don't necessarily need a separate connection for each request. You just need one connection handling one request at a time. To handle multiple request on one connection, you need to execute a new request in the callback of the previous one, after it's finished. For example, Завтра уже попробую, что то в голову ничего не приходит уже.... если кто сталкивался - напишите пожалуйста. Заранее благодарен |
Цитата:
Так вот, у меня только одно соединение с БД при старте сервера. Далее любой запрос по http обрабатывается этим соединением и выдает нужные данные. Поскольку у меня только один логин+пароль, то таких серверов я могу запустить только один. |
Вот так я модернизировал стандартную "раму", что генерит Electron
var myApp = require('../app'); var debug = require('debug')('shop:server'); var http = require('http'); const MongoClient = require('mongodb').MongoClient var port = normalizePort(process.env.PORT || '3000'); MongoClient.connect( 'mongodb://localhost:27017', {useUnifiedTopology: true}, function (err, client) { let db = false if (err) { console.log('Нет контакта с MongoDB') } else { console.log('Контакт с MongoDB') db = client.db('test') } const app = myApp(db) app.set('port', port); var server = http.createServer(app); server.listen(port); server.on('error', onError); server.on('listening', onListening); function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); } } ) function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } |
Постараюсь коротко
Не допускается на один коннект одновременно (тут слово одновременно очень понятие растяжимое) более одного запроса т.е. имеем connect далее запрос let request = new REQUEST(.....) и его выполнение this.connection.execSql(request); так вот, новый new REQUEST только когда полностью отработает вышеуказанный. собственно асинками это не решается. один запрос и его выполнение и так находится в аsync и promise но в это время "прибегает" с другого клиента запрос и все валит. вопрос решается семафором Т.о. если кто столкнется с подобной ошибкой - Requests can only be made in the LoggedIn state, not the SentClientRequest state то кроме того что это означает в переводе, может еще быть наличие конкурирующего запроса, который ломится в модуль mssql при незавершенном предыдущем запросе. И значит новый запрос просто нужно попридержать. ставим семафор, вешаем на него сопли типа await и все работает. Всем спасибо P.S. server.listen(port); server.on('error', onError); server.on('listening', onListening); по моему сначала ставятся обработчки потом начинается, прослушивание порта... не примите как умничание |
Цитата:
Элемент serverявляется наследником эвент эмитера - значит можно вешать слушателей событий. Другое дело инициировать те события начнут только после server.listen() Но именно последовательность вызовов не важна. |
Часовой пояс GMT +3, время: 08:48. |