21.01.2022, 15:23
|
Интересующийся
|
|
Регистрация: 30.10.2020
Сообщений: 10
|
|
GET запросы становятся в очередь.
Пример учебный. Пытаюсь понять.
1) Я получаю get запрос start1 и запускаю асинхронную функцию (в примере вызов скрипт питона, там просто таймер на 6 сек).
2) Не дожидаясь эти 6 сек отправляю еще раз этот запрос с другой вкладки браузера.
3) Ожидаю что запуск скрипта произойдет параллельно (ну или будет системная ошибка что файл занят), но в итоге второй get запрос выполняется только после того как выполнился первый get запрос.
Но при этом я могу послать одновременно запросы start1 и start2, которые параллельно будут выполнять эту асинхронную функцию не дожидаясь друг друга.
То есть из этого следует что если один клиент отправил GET запрос
с длительностью ответа 6 сек , другой клиент отправивший такой же GET будет ждать это время, даже если ядро и память сервера не загружены?
Я уже применял масштабирование с помощью cluster, но это это же для того что бы занять неиспользуемые ядра процессора.
А что делать что бы один клиент не ждал другого при выполнении для него асинхронной функции?
//express, cors и ssl
let fs = require('fs');
var express = require('express')
var app = express()
const cors = require('cors');
const https = require('https').createServer({
key: fs.readFileSync('./config/ssl/owen.pem'),
cert: fs.readFileSync('./config/ssl/owen.crt'),
}, app);
app.use(cors());
//для запуска скрипта питона в корором таймер на 6 сек
const util = require('util');
const exec = util.promisify(require('child_process').exec);
app.get('/start1', function (req, res) {
my_test()
.then((e) => {res.send('test1 завершил работу')})
})
app.get('/start2', function (req, res) {
my_test()
.then((e) => {res.send('test2 завершил работу')});
});
let i = 1;
async function my_test(){
let number = i;
i++;
console.log('старт скрипта ' + number);
const { stdout, stderr } = await exec('/usr/bin/python3 /home/omosencev/temp/test1.py >> test1.log 2>&1');
console.log('конец скрипта ' + number);
return
}
https.listen(3011, function () {
console.log('тестовый PORT', 3011)
})
Последний раз редактировалось Oleg_Lugaro, 24.01.2022 в 09:57.
|
|
21.01.2022, 15:42
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сообщение от Oleg_Lugaro
|
А что делать что бы один клиент не ждал другого при выполнении для него асинхронной функции?
|
Ну у тебя там async/await... Т.ч. асинхронность у тебя ну очень условная.
Но пример меня заинтересовал. Если будет время - потестю его на именно асинхронных запросах.
Поскольку поведение при start1+start1 меня удивило.
|
|
21.01.2022, 16:05
|
Интересующийся
|
|
Регистрация: 30.10.2020
Сообщений: 10
|
|
Сообщение от ksa
|
Ну у тебя там async/await... Т.ч. асинхронность у тебя ну очень условная.
Но пример меня заинтересовал. Если будет время - потестю его на именно асинхронных запросах.
Поскольку поведение при start1+start1 меня удивило.
|
Разве условная? Я добавил логи после then, и они срабатывают не дожидаясь выполнения моей асинхронной функции.
|
|
21.01.2022, 16:09
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сделал такой пример для теста...
const app = require('express')()
const host = '127.0.0.1'
const port = 7000
app.get('/start1', (req, res) => {
test()
.then(_ => res.send('test1 завершил работу'))
})
app.get('/start2', (req, res) => {
test()
.then(_ => res.send('test2 завершил работу'))
})
app.use((req, res, next) => {
res.status(404).type('text/plain')
res.send('Not found')
})
app.listen(port, host, function () {
console.log(`Server listens http://${host}:${port}`)
})
let i = 0
function test() {
return new Promise((resolve, reject) => {
const number = ++i
console.log('старт скрипта ' + number)
setTimeout(_ => {
console.log('конец скрипта ' + number)
resolve()
}, 6000)
})
}
Все повторилось как и в твоем варианте...
Если стартовать start1+start1, сообщения выводятся так
старт скрипта 1
конец скрипта 1
старт скрипта 2
конец скрипта 2
Т.е. пока не получит ответ первый запрос, вторая обработка стартовать не станет.
Если стартовать start1+start2, сообщения выводятся
старт скрипта 3
старт скрипта 4
конец скрипта 3
конец скрипта 4
|
|
21.01.2022, 16:16
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Немного добавил инфы по тесту...
const app = require('express')()
const host = '127.0.0.1'
const port = 7000
let s1 = 0
app.get('/start1', (req, res) => {
const number = ++s1
console.log('Запрос start1 ' + number)
test()
.then(_ => res.send('test1 завершил работу'))
})
let s2 = 0
app.get('/start2', (req, res) => {
const number = ++s2
console.log('Запрос start2 ' + number)
test()
.then(_ => res.send('test2 завершил работу'))
})
app.use((req, res, next) => {
res.status(404).type('text/plain')
res.send('Not found')
})
app.listen(port, host, function () {
console.log(`Server listens http://${host}:${port}`)
})
let i = 0
function test() {
return new Promise((resolve, reject) => {
const number = ++i
console.log('старт скрипта ' + number)
setTimeout(_ => {
console.log('конец скрипта ' + number)
resolve()
}, 6000)
})
}
Вывод сообщений...
Запрос start1 1
старт скрипта 1
конец скрипта 1
Запрос start1 2
старт скрипта 2
конец скрипта 2
Запрос start1 3
старт скрипта 3
Запрос start2 1
старт скрипта 4
конец скрипта 3
конец скрипта 4
Т.е. даже обработка запроса не "освобождается" пока не даст ответ на первый запрос...
|
|
21.01.2022, 16:19
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сообщение от Oleg_Lugaro
|
Я добавил логи после then, и они срабатывают не дожидаясь выполнения моей асинхронной функции
|
Ты сделай логи в async/await...
|
|
21.01.2022, 16:22
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сообщение от ksa
|
Немного добавил инфы по тесту...
|
package.json, если кто будет пробовать...
{
"name": "tmp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.2"
}
}
|
|
21.01.2022, 16:53
|
Интересующийся
|
|
Регистрация: 30.10.2020
Сообщений: 10
|
|
Сообщение от ksa
|
Ты сделай логи в async/await...
|
Ну для самого запроса она должна же выглядить как промис. Если сделать console.log(my_test()) в консоли будет промис.
Ну ладно. Я сделал без промисов и асинк: результат тот же... Наблюдаю что запросы обрабатываться последовательно по очереди.
//express, cors и ssl
let fs = require('fs');
var express = require('express')
var app = express()
const cors = require('cors');
const https = require('https').createServer({
key: fs.readFileSync('./config/ssl/owen.pem'),
cert: fs.readFileSync('./config/ssl/owen.crt'),
}, app);
app.use(cors());
//для запуска скрипта питона в корором таймер на 6 сек
const { exec } = require('child_process');
app.get('/start1', function (req, res) {
my_test(res, '1')
console.log('21 сточка');
})
app.get('/start2', function (req, res) {
my_test(res, '2')
console.log('27 сточка');
});
function my_test(res, i){
console.log(`старт скрипта test${i}`);
exec('/usr/bin/python3 /home/omosencev/temp/test1.py >> test1.log 2>&1', (error, stdout, stderr) => {
if (error) {
res.send(error);
return;
}
console.log(`test${i} завершил работу`);
res.send(`test${i} завершил работу`)}
);
return
}
https.listen(3011, function () {
console.log('тестовый PORT', 3011)
})
|
|
21.01.2022, 16:56
|
Интересующийся
|
|
Регистрация: 30.10.2020
Сообщений: 10
|
|
Сообщение от ksa
|
Т.е. даже обработка запроса не "освобождается" пока не даст ответ на первый запрос...
|
Вот это и интересно. Причем другие запросы свободны.
|
|
21.01.2022, 17:34
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сообщение от Oleg_Lugaro
|
Причем другие запросы свободны.
|
Ну они же "другие"...
Видно другой обработчик "свободен", потому и принимает запрос.
|
|
|
|