Есть сервер, который по запросу клиентов отправляет им определенные данные.
Например, клиент отправляет через TCP сокет последовательно id’шники желаемых блоков данных, сервер их загружает в память и по сути сразу же запускает асинхронную отправку
У меня возник вопрос, как сделать так (архитектура программы), чтобы один и тот же блок данных не грузился 2 раза, если 2 разных клиента попросили один и тот же блок ?
Дело осложняется тем, что отправка не моментальная, ну и async write же требует, чтобы данные находились в памяти до тех пор, пока не придет калбек о том, что отправка завершилась успешно
У меня есть идея
-
загружать блок в условную MAP вида, этим гарантируем, что он не загрузится дважды. Если блок уже есть в мапе, то просто обновляем список получателей (id блока) - (char *, список получателей: юзер 1, юзер 2, …)
-
Запускаем отправку async write
-
Калбек функция async write вычеркнет юзера из списка получателей и, если он пустой, освободит буффер и удалит элемент из мапы.
Это вообще адекватно ? Я просто не знаток многопоточного программирования, а к этой мапе доступ будут иметь 2 потока : поток, который занимается отправкой сообщений, а также поток, который занимается тем, что ложит туда данные (и он же вызывает функцию отправки у первого по оставленному указателю на соединение)
То есть если я просто сделаю условно класс thread safe map и приделаю туда мьютекс, то это же будет работать ? (почему нет)
и в калбеке async write будет вызываться функция наподобие
{
std::unique_lock<std::mutex> lock(_mtx);
map.myList.erase(...user_id);
if(myList.empty())
{
delete [] buffer;
map.erase (...)
}
}
Хотя чисто интуитивно if под мьютексом выглядит как трэш какой-то. В общем помогите, пожалуйста, или накидайте альтернативных идей, с меня как обычно.