Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.01.2022, 15:23
Интересующийся
Отправить личное сообщение для Oleg_Lugaro Посмотреть профиль Найти все сообщения от Oleg_Lugaro
 
Регистрация: 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.
Ответить с цитированием
  #2 (permalink)  
Старый 21.01.2022, 15:42
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,123

Сообщение от Oleg_Lugaro
А что делать что бы один клиент не ждал другого при выполнении для него асинхронной функции?
Ну у тебя там async/await... Т.ч. асинхронность у тебя ну очень условная.

Но пример меня заинтересовал. Если будет время - потестю его на именно асинхронных запросах.
Поскольку поведение при start1+start1 меня удивило.
Ответить с цитированием
  #3 (permalink)  
Старый 21.01.2022, 16:05
Интересующийся
Отправить личное сообщение для Oleg_Lugaro Посмотреть профиль Найти все сообщения от Oleg_Lugaro
 
Регистрация: 30.10.2020
Сообщений: 10

Сообщение от ksa Посмотреть сообщение
Ну у тебя там async/await... Т.ч. асинхронность у тебя ну очень условная.

Но пример меня заинтересовал. Если будет время - потестю его на именно асинхронных запросах.
Поскольку поведение при start1+start1 меня удивило.
Разве условная? Я добавил логи после then, и они срабатывают не дожидаясь выполнения моей асинхронной функции.

Ответить с цитированием
  #4 (permalink)  
Старый 21.01.2022, 16:09
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,123

Сделал такой пример для теста...
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
Ответить с цитированием
  #5 (permalink)  
Старый 21.01.2022, 16:16
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,123

Немного добавил инфы по тесту...
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

Т.е. даже обработка запроса не "освобождается" пока не даст ответ на первый запрос...
Ответить с цитированием
  #6 (permalink)  
Старый 21.01.2022, 16:19
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,123

Сообщение от Oleg_Lugaro
Я добавил логи после then, и они срабатывают не дожидаясь выполнения моей асинхронной функции
Ты сделай логи в async/await...
Ответить с цитированием
  #7 (permalink)  
Старый 21.01.2022, 16:22
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,123

Сообщение от 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"
  }
}
Ответить с цитированием
  #8 (permalink)  
Старый 21.01.2022, 16:53
Интересующийся
Отправить личное сообщение для Oleg_Lugaro Посмотреть профиль Найти все сообщения от Oleg_Lugaro
 
Регистрация: 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)
})
Ответить с цитированием
  #9 (permalink)  
Старый 21.01.2022, 16:56
Интересующийся
Отправить личное сообщение для Oleg_Lugaro Посмотреть профиль Найти все сообщения от Oleg_Lugaro
 
Регистрация: 30.10.2020
Сообщений: 10

Сообщение от ksa Посмотреть сообщение
Т.е. даже обработка запроса не "освобождается" пока не даст ответ на первый запрос...
Вот это и интересно. Причем другие запросы свободны.
Ответить с цитированием
  #10 (permalink)  
Старый 21.01.2022, 17:34
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,123

Сообщение от Oleg_Lugaro
Причем другие запросы свободны.
Ну они же "другие"...
Видно другой обработчик "свободен", потому и принимает запрос.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как написать запросы с помощью swagger спецификации? jtag Node.JS 0 15.09.2018 16:05
Вложенные Ajax запросы Sherminator AJAX и COMET 10 03.10.2016 05:11
Как поставить мои ajax запросы в очередь? Romingood AJAX и COMET 1 18.10.2013 23:38
Очередь XML запросов Евгений М AJAX и COMET 4 01.02.2012 11:05
Кроссдоменные запросы aze AJAX и COMET 1 27.01.2012 02:43