Комментарии 15
С релизом можно и в cci уезжать. Поздравляю
Приятно было поучаствовать и познакомиться лично ?
«На некоторые проблемы многопоточности userver понятную диагностику по их исправлению на этапе компиляции»
Какие конкретные проблемы? Дайте пример или ткните в код в репозитории, пожалуйста)
Вот например код:
const auto& data = cache.Get()[some_user];
foo(data);
Кажется что всё ОК, и тесты вам покажут что всё ОК. Однако, гард защищающий содержимое от конкурентных обновлений, будет уничтожен на первой строчке, а значит что data потенциально может обновиться в фоне и ссылка начнёт указывать на невалидные данные или недоступную память. И такую проблему фиг осознаешь!
И проблемы случатся уже в проде! Нет, не случатся! Такой код не скомпилируется, сообщение об ошибке попросит вас сохранить гард на стеке:
const auto snapshot = cache.Get();
const auto& data = snapshot[some_user];
foo(data);
Для предотвращения подобных ситуаций есть класс SharedReadablePtr, многие RCU-подобные классы устроены так же (например rcu::ReadablePtr).
Применим ли данный фреймворк не только в рамках IO-bound программы, а при смешанной нагрузке? Что-то прочли, многопоточно посчитали, отправили результат далее.
Да, применим. У нас многие сервисы именно с таким профилем
Чтобы начать что-то многопоточно считать обычно используется utils::Async или AsyncNoSpan, множество задач дожидаются через GetAll или WaitAny. Для более сложных синхронизаций между задачами, созданными через Async*, есть целый набор примитивов синхронизации и многопоточных контейнеров.
Если у вас какая-то особая специфика или возникнут проблемы - говорите, поможем либо здесь, либо в официальном чатике поддержки.
У вас интересное замечание там.
Use of the C++ standard library and libc synchronization primitives in coroutines is forbidden.
Я правильно понимаю, что это распространяется на любой код, вызываемый в обработчиках? Например, есть библиотека чтения данных, у неё есть общий кэш, защищённый мьютексом, получается, я не могу её использовать? И так надо проводить анализ всех зависимостей? А если mutex не из std и libc, а из pthreads или openmp, то можно?
Всё верно, нельзя пользоваться никакими сторонними блокирующими примитивами синхронизации и блокирующими операциями из основного таск процессора (тред пула).
Точнее, можно. Но на большой нагрузке это станет узким местом и вам придётся выносить работу с такой библиотекой в отдельный таск процессор (тред пул).
Делается это легко - передаёте нужный таск процессор в utils::Async
P.S.: мы распишем этот момент в документации поподробнее
userver 1.0 — релиз фреймворка для IO-bound программ