Показать сообщение отдельно
  #126 (permalink)  
Старый 09.01.2023, 21:33
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,754

const buffer = new Set();
 
const pool = new Map();

// Допустим выполнялся запрос

const req0 = {from:"Петя", to: "Вася", action:"5 бочек апельсинов"}
// В buffer было добавлено
buffer.add('Петя');
buffer.add('Вася');

// Теперь приходит запрос
// <Вася> решил 1 бочку апельсинов передать <Мише>

const req1 = {from:"Вася", to: "Миша", action:"1 бочек апельсинов"}

// Выясняем есть "Вася" или "Миша" в buffer (Вася есть)
// Если есть то записываем обоих в pool
// Здесь я использую массивы, но лучше нормальную списковую очередь

if (inBuffer(req1.from) || inBuffer(req1.to)) {
	if (!pool.has(req1.from)) pool.set(req1.from, [])
	pool.get(req1.from).push(req1)
	if (!pool.has(req1.to)) pool.set(req1.to, [])
	pool.get(req1.to).push(req1)
}

// Теперь приходит запрос <Вася> решил 1 бочку апельсинов передать <Катя>

const req2 = {from:"Вася", to: "Катя", action:"1 бочек апельсинов"}

// Выясняем есть "Вася" или "Катя" в buffer (Вася есть)
// Если есть то записываем обоих в pool

if (inBuffer(req2.from) || inBuffer(req2.to)) {
	if (!pool.has(req2.from)) pool.set(req2.from, [])
	pool.get(req2.from).push(req2)
	if (!pool.has(req2.to)) pool.set(req2.to, [])
	pool.get(req2.to).push(req2)
}

// В пуле у нас
// Вася => [req1, req2]
// Миша => [req1]
// Катя => [req2]

// Теперь заканчивается запрос req0 = {from:"Петя", to: "Вася", action:"5 бочек апельсинов"}
// Петя и Вася удаляются из буфера
buffer.delete('Петя');
buffer.delete('Вася');

Раз запрос закончился мы проверяем есть ли запросы с Петя и Вася в pool
C Петя - нет.
Берем в пуле у Вася первый запрос
это req1 = {from:"Вася", to: "Миша", action:"1 бочек апельсинов"}
Тут мы должны определить второго участника запроса. Это Миша.
Проверяем Миша в buffer
Если нет, смотрим первый запрос в пуле у Миши
Если это ТОТ ЖЕ запрос, (req1 === req1), то он может быть отправлен на выполнение.
Но сначала удалим его из пулов для Вася и Миша
При этом, если очередь участника пуста, то надо удалить и самого участника из пула

И дальше все в событийных циклах. Пришел запрос - либо на выполнение, либо в пул
Завершился запрос - смотрим в пуле есть ли еще запросы с этими участниками и могут ли они быть исполнены

Единственное, что мне кажется, когда приходит запрос, мы должны проверять участников не только в buffer (запросы с ними выполняются и еще не закончены), но и в pool (у участника есть более ранние запросы, которые еще и не начали выполняться). Если какое то условие выполнено - помещаем запрос в pool. Если нет - путь свободен - можем сразу посылать запрос на выполнение.

Последний раз редактировалось voraa, 09.01.2023 в 21:41.
Ответить с цитированием