03.06.2021, 23:32
|
|
Кандидат Javascript-наук
|
|
Регистрация: 01.03.2021
Сообщений: 138
|
|
node + mssql
Всем здравия! Господа, может кто сталкивался, вот такое дело:
имеем серверную часть node. в ней объект работы с mssql сделан в виде объекта и объявлен как константа. другими словами один объект открывает connect и держит его для любого подключения. если коннект обрывается он опять его коннектит. т.е. коннект всегда актуален.
К серверу подключаются клиенты. Подключился один клиент, выдал серверу команду. вместе с сервером клиент начинает отрабатывать некий цикл задач. все вроде бы нормально. Подключился второй и так далее.
Но выявилось что, как только клиент за одно обращение передает команду которая требует нескольких операций с mssql за раз на сервере - сервер делает первую и дальше выдает ошибку, что нужно сначала дождаться логина и только потом выполнять запрос. Фигня какая то. Причем у него статус LoginIn находится в состоянии true.
Возникает ощущение что на каждый запрос нужно делать коннект! Фигня какая то. С другой стороны несколько клиентов могут полчаса долбить его и все нормально. Первое обращение с несколькими запросами (выполняются на сервере ПОСЛЕДОВАТЕЛЬНО) на одном клиентском соединении - и пипец.
Есть идеи?
|
|
03.06.2021, 23:34
|
|
Кандидат Javascript-наук
|
|
Регистрация: 01.03.2021
Сообщений: 138
|
|
неужели нужно постоянно долбить mssql коннектами? долго и неэффективно
|
|
04.06.2021, 01:11
|
|
Профессор
|
|
Регистрация: 07.03.2011
Сообщений: 1,138
|
|
Сумбурное объяснение но ты уверен что у тебя достаточно лицензий куплено чтобы держать больше пяти одновременных подключений?
|
|
04.06.2021, 01:21
|
|
Кандидат Javascript-наук
|
|
Регистрация: 01.03.2021
Сообщений: 138
|
|
Могу еще перегрузить модем, может поможет?
|
|
04.06.2021, 01:22
|
|
Кандидат Javascript-наук
|
|
Регистрация: 01.03.2021
Сообщений: 138
|
|
ответ есть вот здесь.
https://github.com/tediousjs/tedious/issues/458
походу так и есть...... на каждые request -> connect.
хотя бред, не может такого быть....
|
|
04.06.2021, 01:26
|
|
Кандидат Javascript-наук
|
|
Регистрация: 01.03.2021
Сообщений: 138
|
|
во как пишут...
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,
Завтра уже попробую, что то в голову ничего не приходит уже.... если кто сталкивался - напишите пожалуйста.
Заранее благодарен
|
|
04.06.2021, 08:07
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,215
|
|
Сообщение от fxobject
|
неужели нужно постоянно долбить mssql коннектами?
|
Я работаю с MongoDB, но суть по соединениям с БД там одинаковая...
Так вот, у меня только одно соединение с БД при старте сервера. Далее любой запрос по http обрабатывается этим соединением и выдает нужные данные.
Поскольку у меня только один логин+пароль, то таких серверов я могу запустить только один.
|
|
04.06.2021, 08:43
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,215
|
|
Вот так я модернизировал стандартную "раму", что генерит 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;
}
|
|
04.06.2021, 11:21
|
|
Кандидат Javascript-наук
|
|
Регистрация: 01.03.2021
Сообщений: 138
|
|
Постараюсь коротко
Не допускается на один коннект одновременно (тут слово одновременно очень понятие растяжимое) более одного запроса
т.е. имеем 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);
по моему сначала ставятся обработчки потом начинается, прослушивание порта...
не примите как умничание
|
|
04.06.2021, 13:52
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,215
|
|
Сообщение от fxobject
|
по моему сначала ставятся обработчки потом начинается, прослушивание порта...
|
Это без разницы...
Элемент
server
является наследником эвент эмитера - значит можно вешать слушателей событий.
Другое дело инициировать те события начнут только после
server.listen()
Но именно последовательность вызовов не важна.
Последний раз редактировалось ksa, 04.06.2021 в 13:55.
|
|
|
|