Мы снимали метрики за каждый будний день, и сравнивали 80-ый персентиль c начальным 80-ым персентилем. На скриншоте по сути видны результаты за последний день соревнования.
По некоторым командам хорошо видно в какой день они выкатили какую то оптимизацию, потому что значение резко менялось
Ну вообще говоря эту линию между scala и java миром можно сгладить восстановив контекст при возвращении в scala. Примерный псевдокод:
val context = MDC.getCopyOfContextMap()
runMethodThatWillInteractWithJavaAsync().andThen {
case _ => MDC.setContext(context) // я точно не знаю какой тут должен быть метод
}.map { result => ... //Тут у вас уже опять родной контекст и далее по пути следования
}
Да вы можете потерять часть логов внутри java библиотеки, но это, я считаю, совсем мелочи
Не очень понимаю как я перехитрил компилятор и метод. По поводу использования в сигнатуре метода я писал.
Первое, что может прийти в голову, это передавать контекст через имплиситный аргумент функции.
def foo(bar: Bar)(implicit context: Context)
Но это будет захламлять протокол сервисов.
И как вызывающий поймет, что ему необходимо передать какой-то контекст?
Никто никого не обманывает, если проект пошел на использование этой идеи, то это можно считать контрактом. В точке входа нужно вызвать withContext, больше нигде этого делать не нужно.
Для этого обычно используется явно объявление параметров метода
да, если этих метод полторы штуки, то ок. Но если вам нужно чтобы весь код нуждается в контесте, тоооо будет жутко мазолить глаза. Опять же это решится с ImplicitFunction как и упомяналось выше
ситуацию спасает scala.concurrent.ExecutionContext#prepare собственно его дергает Future перед запуском таска. То есть на вызове этого метода создается новый инстанс контекста, в который можно записать что либо. Или который как раз будет при запуске затаска заполнять ThreadLocal нужным значением
Есть подозрение, что вы как то неправильно его используете. У нас крутится несколько приложений на подходе похожем на MDC. Для того, чтобы это работало, нужно:
чтобы все операции исполнялись в ExecutorContext'ах, которые реализуют логику по изменению ThreadLocal
по дороге не было ничего, что может потерять контекст. Например, акторы, но есть решение и для них
Количество тасков в контекстах не играет никакой роли. Если опишите поподробнее ситуацию, я скорее всего подскажу как её решить
Логирование — это самый простой и примитивный пример.
Если опять же говорить про веб бекенд, то там можно хранить сессию и пользователя например, но это наверное спорное применение.
Но вот я в статье упомянул, что можно передавать слепок состояния. То есть у тебя есть какие то данные, которые переодически обновляются (например кеш конфигов приложения или справочники). И вот перед тобой стоит задача — гарантировать, что при выполнении одного запроса эти состояния будут одинаковыми во всех сервисах. И вот подобный контекст уже отлично ложится на эту ситуацию. Мы взяли вначале операции сделали snapshot состояния, и сделали всё что нужно с используя его.
Вобщем проблема не разу не подгонялась под решение, решение радилось из-за проблемы
Нет, и мысли переизобретать комонады не было. Хотелось сделать так, чтобы остальной бизнесс код приложения никак не почувствовал на себе наличие или отсутствие этого кода. И чтобы код и дальше оставляя чистым и простым для чтения и понимания.
Про имплиситную функцию, спасибо за видосик идея очень интересная, реальное решит проблему с контекстами, если весь протокол сервисов будет построен на таком типе функций.
Это только поначалу неудобно. Когда вы втягиваетесь в функциональное программирование, становится трудно остановиться. Сначала монады, потом трансформеры, потом Free, потом eff.
Звучит очень опасно :) Это как бы использовать вилку, чтобы есть суп, только по началу не удобно, вот такая вот ассоциация
честно, такое у нас тоже есть, но меня напрягает что на каждом таске происходит одно чтение из тред локали и 2 записи. И эта же идея используется врапере для контекста, кстати
И еще помимо микроразметки рендер spa на сервере уменьшает трафик и количество запросов для первого рендера страницы, так как все возможные запросы для получения данных не покидают сервера.
Чтобы приложение было менее зависимо от БД я создал обертку NoteWrapper над нашей моделью, в которой будут происходить все операции по созданию, сохранению, обновлению и удалению заметок
Кажется это называется DAO, Wrapper — это совершенно другой паттерн
А в чем собственна проблема работы с данными в реакте, если у нас данные и отображение разделены, мы просто меняем данные и отображение рефлектирует эти данные. По мне это один самых простых подходов в работе с данными на клиенте.
P.S. Ну вообще конечно делать подобные манипуляции на клиенте вообще сомнительно, ибо это должно делаться на сервере
Мы снимали метрики за каждый будний день, и сравнивали 80-ый персентиль c начальным 80-ым персентилем. На скриншоте по сути видны результаты за последний день соревнования.
По некоторым командам хорошо видно в какой день они выкатили какую то оптимизацию, потому что значение резко менялось
Всё проще, люди используют одни и те же пароли везде, а они уже 100 раз утекли в сеть. Остаётся только найти номер телефона клиента
Да вы можете потерять часть логов внутри java библиотеки, но это, я считаю, совсем мелочи
Никто никого не обманывает, если проект пошел на использование этой идеи, то это можно считать контрактом. В точке входа нужно вызвать withContext, больше нигде этого делать не нужно.
да, если этих метод полторы штуки, то ок. Но если вам нужно чтобы весь код нуждается в контесте, тоооо будет жутко мазолить глаза. Опять же это решится с ImplicitFunction как и упомяналось выше
Количество тасков в контекстах не играет никакой роли. Если опишите поподробнее ситуацию, я скорее всего подскажу как её решить
Если опять же говорить про веб бекенд, то там можно хранить сессию и пользователя например, но это наверное спорное применение.
Но вот я в статье упомянул, что можно передавать слепок состояния. То есть у тебя есть какие то данные, которые переодически обновляются (например кеш конфигов приложения или справочники). И вот перед тобой стоит задача — гарантировать, что при выполнении одного запроса эти состояния будут одинаковыми во всех сервисах. И вот подобный контекст уже отлично ложится на эту ситуацию. Мы взяли вначале операции сделали snapshot состояния, и сделали всё что нужно с используя его.
Вобщем проблема не разу не подгонялась под решение, решение радилось из-за проблемы
Если не прав, попровьте, плиз
Звучит очень опасно :) Это как бы использовать вилку, чтобы есть суп, только по началу не удобно, вот такая вот ассоциация
или я вас не понял
Как будут по вашему выглядеть сервисы, если всё вокруг обвешать ридерами?
Этот способ позволяет минимизировать различие между кодом с и без контекста.
Честно мне не попадалось на глаза решения подобной проблемы
Кажется это называется DAO, Wrapper — это совершенно другой паттерн
P.S. Ну вообще конечно делать подобные манипуляции на клиенте вообще сомнительно, ибо это должно делаться на сервере