|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
На новом проекте встретил очень частое использование CompletableFuture. "Частое" это слабо сказано, почти сплошняком. Проект - типичный rest со spring внутри. CompletableFuture используется везде: в контроллерах, сервисах, репозиториях. Почти все методы возвращают или принимают CompletableFuture. Может это и нормально, но как-то непривычно. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 16:29 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Уточнение. Почти все методы возвращают или принимают CompletableFuture/ ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 16:32 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Или это какой-то новый стиль программирования и все что касается работы с ресурсами (базы, файлы и т.п.) нужно делать через CompletableFuture. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 16:47 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 Или это какой-то новый стиль программирования и все что касается работы с ресурсами (базы, файлы и т.п.) нужно делать через CompletableFuture. Все правильно, это пародия на функциональное программирование, но увы из-за долгой истории java эти концепты не получается сделать красиво и на мой взгляд код становится просто п..ц ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 17:17 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970, Сабж служит для удобного асинхронного кодирования. Вопрос, нужна ли асинхронность при БАНАЛЬНОМ REST? Мое имхо - не нужна. Платформа java и контейнер аппСервера сделали все чтобы прогер не задумывался о потоках и асинхронности. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 18:48 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp bob1970, Сабж служит для удобного асинхронного кодирования. ... Видел бы ты это удобно. Мозг в трубочку сворачивается. Представь себе код, где обычные объекты практически не используются, все завернуто в CompletableFuture. Я не против CompletableFuture. Все правильно. И удобно, и производительность. Но где грань применимости? Понятно что при обращении к внешним медленным ресурсам, и тогда получается что правильно запросы к БД нужно делать через CompletableFuture. Как-то бы определить эту границу. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 19:26 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 Все правильно. И удобно, и производительность. Но где грань применимости? Понятно что при обращении к внешним медленным ресурсам, и тогда получается что правильно запросы к БД нужно делать через CompletableFuture. Как-то бы определить эту границу. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 19:47 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов, Удобно/неудобно. Размышляю пока. Почему выбрано такое решение. Вот пару ссылок: CompletableFuture : A new era of asynchronous programming Сама статья ниочем, но заголовок внушает. И другая Synchronous or asynchronous, and why wrestle with wrappers? Может и в самом деле ушла эра синхронного программирования. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 20:27 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 Может и в самом деле ушла эра синхронного программирования. Вот для просветления: Чем асинхронные сервлеты отличаются от Sping WebFlux ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 20:55 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970, мы-же кода не видели. Вполне возможно что существует кейс когда асинхронные микро-задачки удобны. Как-по мне - не очень. Неудобно отслеживать статус ошибки. Если у тебя вся логика - короткая и отбивается одним методом рест-контроллера - тогда ручная CompletableFuture - не имеет смысла. Сам рест-контроллер и так обеспечивает множество конкурирующих сеансов. Чтобы понять что CompletableFuture являлся ненужным обвесом - надо взять полностью этот проект и переписать на классической rest архитектуре и просто посмотреть как оно вышло. Возможно кода станет меньше. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 20:58 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
mayton мы-же кода не видели. Там страшно. Очень. mayton Вполне возможно что существует кейс когда асинхронные микро-задачки удобны. Именно. Меня бы не смутили мелкие вставки, обращения к микро=задачкам. Но когда все. Сплошь. Маленький пример: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Это базовый репозиторий. Как можно понять все остальные репо-ии наследуются. Сервисы , контроллеры в том же духе. Ну и можете представить implementation. mayton Чтобы понять что CompletableFuture являлся ненужным обвесом - надо взять полностью этот проект и переписать на классической rest архитектуре и просто посмотреть как оно вышло. Возможно кода станет меньше. Это нереально. Очень много кода. В общем-то тему, наверное, нужно переименовать в Реактивная Java и закрыть. А решать каждый для себя. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 21:25 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970, а как при таком контракте репозитория хоть какую-то бизнес-логику организовать (ну банально: записать информацию о транзакции и списать сумму со счета)? или там CRUD и ничего больше? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 21:33 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 Видел бы ты это удобно. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 21:53 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Если рассмотреть такой упрощенный круд-реп Код: java 1. 2. 3. 4.
И я допустим хочу с ним поработать. Я добавил документ entity. И вызываю сраз-же getItemReference. Код: java 1. 2.
И во второй строке я получаю ошибку или исключение. Мой фьючерс еще не завершил работу. Тоесть я видимо как-то не так работаю. Очевидно чтобы гарантировать что причинно-следственная цепочка отработала я должен ставить искусственный барьер на первый и второй фьючерс. И усложнять простой и очевидный код. И теперь вопрос. Ради чего это делалось? И ведь это даже не CQRS. В той методике есть хотя-бы темпоральная хронология в КОМАНДАХ. Команда которая дана раньше - раньше будет исполнена. Но только не здесь. Почему нельзя было просто сделать так? Код: java 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 21:56 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов, Примерно так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
И повторюсь -там не только CRUD. Там ВСЕ. Вообще ВСЕ. Сервисы с бизнес-логикой, контроллеры и прочий код. Все на future ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 21:58 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp, Сравни Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
и Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Это отсюда ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:07 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Как будто-бы калька с другого фреймворка. Может даже не на Java а на другом языке или технологии где такие штуки красиво заворачиваются в аспекты или лябды. Здесь как-бы мясо вот серединке Код: java 1. 2. 3.
А сверху и снизу просто одинаковые обёртки которые обеспечивают трансфер in/out параметров. Вот почему мне и напомнило аспекты. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:08 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
mayton, Да, это главное. Но как завернуто Код: java 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:11 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 Примерно так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:11 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов, Примерно так Код: java 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:15 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 Примерно так Код: java 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:18 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов А на ACID забить? Оххх... Там до таких страшных слов, как до Китая. А вообще, я не про конкретный проект. Я про подход. Реактивная Java есть и используется. И похоже использовать ее нужно как-то так. Короче, надо изучать это дело. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:24 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
mayton Почему нельзя было просто сделать так? Код: java 1. 2. 3. 4.
Это самый главный вопрос. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.03.2020, 22:32 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 Или это какой-то новый стиль программирования и все что касается работы с ресурсами (базы, файлы и т.п.) нужно делать через CompletableFuture. ты прям плей фреймворк описал ))) в нем тоже все возвращает футуры. все что связано с взаимодействием со сторонними сервисами или ресурсами (бд, веб, акторы и тп) ... |
|||
:
Нравится:
Не нравится:
|
|||
22.03.2020, 00:31 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
bob1970 PetroNotC Sharp bob1970, Сабж служит для удобного асинхронного кодирования. ... Видел бы ты это удобно. Мозг в трубочку сворачивается. Представь себе код, где обычные объекты практически не используются, все завернуто в CompletableFuture. Я не против CompletableFuture. Все правильно. И удобно, и производительность. Но где грань применимости? Понятно что при обращении к внешним медленным ресурсам, и тогда получается что правильно запросы к БД нужно делать через CompletableFuture. Как-то бы определить эту границу. дело привычки. мозг перестает скручиваться в трубку если ты постоянно тащишь все через функторы монады (мап флатмап или зенкомпос зенаплай вроде). да. это асинхронка, но вот мне лично кажется, что в этих кишках ошибки ловить прям отдельный челлендж. особенно когда проблемы возникают с многопоточкой. а они возникают. кто говорит нет - тот обманывает. другая проблема. у джавы комплитабл фьюча выглядит как гамно. в скале лучше. в ней хоть форкомпрехеншн есть который отображает это не в таком идиотском виде. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.03.2020, 00:34 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Стас. Ты? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.03.2020, 10:39 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Заколебал усы менять. Прибереги хоть этот акк. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.03.2020, 12:11 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Zzz79 Таже самая петрушка и у нас- кто то один увидел эту шляпу и теперь она сплошь и рядом во всех наших сервисах,где надо и где не надо ловить ошибки становится тяжело,код превращается в какую то трудно поддерживаемую шляпу по этому поводу недавно у нас был митинг - сказали теперь каждый стрим и комплфьючер должен быть обоснован иначе получите по щщам я вот не пойму ты то откуда знаешь где надо где не надо. у реактивочки есть свой прикол. хотя не уверен насколько он обоснован но есть мнение что помогает избегать ряд ошибок. ну и конечно же писать функциональные колбаски. (которые фиг расширишь если надо) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.03.2020, 14:44 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов bob1970 Примерно так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 10:09 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
WGA Т.е. несколько обращений к репозиторию в одну транзакцию вообще не объединить? Код: java 1. 2. 3. 4. 5. 6. 7.
Из-за того, что транзакцию прилепить некуда в сущностях нельзя использовать поля с FetchType.LAZY, ну или вообще поля с сущностями использовать нельзя, а только идентификаторы, в следствие чего вылезают какие-то нереальные грабли, например: - при классическом подходе повторный getItem тащит сущность из памяти, а здесь она каждый раз чистая достается, т.е. если сущность у нас мутирует, то ее придется постоянно по стэку таскать (еще и код более тщательно ревьювить) - использование идентификаторов в полях сущностей убивает кучу возможностей, предоставляемых Criteria API, в т.ч. статическую типизацию т.е. получается, что взяли довольно тяжелый ОРМ, у которого есть куча своих проблем, начали его использовать через Ж, и растеряли все его преимущества, которые хоть как-то нивелировали его тяжесть. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 10:37 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
WGA Т.е. несколько обращений к репозиторию в одну транзакцию вообще не объединить? Код: java 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 11:24 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp по старинке это так Код: java 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 12:04 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Топик (CompletableFuture) убивает идею консистентности данных по интерфейсу. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 12:15 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
CompletableFuture - это тупая попытка перетянуть continuation монаду в императивный язык. Стримы хоть как-то взлетели, а эти спекописатели все никак не успокоятся. Ну нельзя перетянуть только часть идеи. Все описанные проблемы решаются в рамках ФП парадигмы, но при этом конечно появляются другие, но не такие ущербные, так что золотой пули все же нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 12:23 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов убивает mayton убивает Надо подумать... ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 12:41 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Язык определяет сознание. Вот с тех пор как Oracle перешел на полу-годичный цикл Sep/March/YYYY релизов - именения пошли просто бешеные. Такого не было до восьмерки. И комьюнити начало закидывать в язык новые идеи. Но новые идеи часто просто украдены из смежных языков и технологий где они органичны. Что еще нужно затащить в этот скромный и консервативный язык чтобы окончательно его превратить в помойку? Хотите язык где есть всё и только чёрта в ступе не хватает? Идите в Scala. Там есть любой анальный вибратор чтоб пощекотать себе очько. И логику можно описать 20 способами. Но нет же. Не идут в Скала. Тяжело там. Хотят мозговой онанизм внутри java. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 12:54 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов PetroNotC Sharp по старинке это так Код: java 1. 2. 3. 4.
Не понял связи. Паттерн репозиторий это работа с коллекцией из бд не замечая самой бд. Транзакции к этому функционалу побоку. ... Понятно, что тут намешено всего. Транзакции jpa, транзакции спринга и менеджер сущностей. Проблема писателей кода. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 15:35 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp подумал.... Не понял связи. Паттерн репозиторий это работа с коллекцией из бд не замечая самой бд. Транзакции к этому функционалу побоку. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 18:15 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов Нет, репозиторий нужен для того, чтобы API для работы с данными (в общем случае не rdbms) не выставлять наружу Андрей Панфилов при этом "по классике" репозиторий сам присоединяется к текущей транзакции Есть ручное управление когда в коде пишу. Есть автоматическое на аннотациях. Декларативное. Они равноправны. И оба мной любимы. Поменять реализацию ОРМ позволяет JPA. Имхо ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 18:43 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp с чего это Сам? jpa specificationThe PersistenceContext annotation is used for entity manager injection. The type element specifies whether a transaction-scoped or extended persistence context is to be used, as described in section 7.6. The synchronization element specifies whether the persistence context is always automatically joined to the current transaction (the default) or is not joined to the current transaction unless the joinTransaction method is invoked by the application. The unitName element may optionally be specified to designate the persistence unit whose entity manager factory is used by the container. The semantics of the persistence context synchronization type are further described in section 7.6.1. Section 10.5.2 provides further information about the unitName element. т.е. чтобы в житуи EM не присоединялся к текущей транзакции нужно специально приседать, спринговая инфраструктура работает точно также, т.е. если у кого-то это не так, то это значит что в проекте творится полная Ж. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2020, 23:23 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов, Ну хорошо, добавляем третий вариант управления транзакциями: - по умолчанию (ничего не пишем) - ручное em.дайТранзакцию.Старт - аннотации Все логично, и меня все три варианта устраивают. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 07:42 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов WGA Т.е. несколько обращений к репозиторию в одну транзакцию вообще не объединить? Код: java 1. 2. 3. 4. 5. 6. 7.
Из-за того, что транзакцию прилепить некуда в сущностях нельзя использовать поля с FetchType.LAZY, ну или вообще поля с сущностями использовать нельзя, а только идентификаторы, в следствие чего вылезают какие-то нереальные грабли, например: - при классическом подходе повторный getItem тащит сущность из памяти, а здесь она каждый раз чистая достается, т.е. если сущность у нас мутирует, то ее придется постоянно по стэку таскать (еще и код более тщательно ревьювить) - использование идентификаторов в полях сущностей убивает кучу возможностей, предоставляемых Criteria API, в т.ч. статическую типизацию т.е. получается, что взяли довольно тяжелый ОРМ, у которого есть куча своих проблем, начали его использовать через Ж, и растеряли все его преимущества, которые хоть как-то нивелировали его тяжесть. Lazy нужно подгружать через @Query(.. JOIN FETCH), тогдо проблем не возникнет, вообще, все связи должны быть LAZY и подгружаться только по необходимости ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 08:46 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp - ручное em.дайТранзакцию.Старт ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 10:21 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов, Угу. И длинных транзакций не существует. И десктопа в мире нету. И без спринга жизни нету. Не надо так узко на java. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 11:00 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp Угу. И длинных транзакций не существует. И десктопа в мире нету. И без спринга жизни нету. Не надо так узко на java. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 12:00 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов Длинные транзакции плохи в web Вы же не сказали "если спринг + если JPA +.... Так как у JPA вообще нет управления транзакциями. Аннотация от спринга. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 12:14 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов, Вы водителей с ручной коробкой тоже не любите? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 12:15 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
PetroNotC Sharp Вы огульно отрицаете ручное управление. PetroNotC Sharp Так как у JPA вообще нет управления транзакциями. Аннотация от спринга. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 12:53 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
Андрей Панфилов Конечно, ручное управление транзакциями - это дичь Андрей Панфилов то подавляющее большинство кода должно присоединяться к уже существующей транзакции, Вы выше сказали что это default. ЭТО НЕ УПРАВЛЕНИЕ ТРАНЗАКЦИЯМИ. Если не писать beginTran руками в коде то так оно и будет. Где вы проблемы увидели? Андрей Панфилов javax.persistence.SynchronizationType - это из какого модуля? Я про аннотации гочорил. Управляют с помощью аннотации. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 13:16 |
|
Очень много CompletableFuture
|
|||
---|---|---|---|
#18+
авторспецификация JPA сама по себе не предоставляет никакого декларативного управления транзакциями http://akorsa.ru/2016/08/kak-na-samom-dele-rabotaet-transactional-spring/ ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2020, 13:20 |
|
|
start [/forum/topic.php?all=1&fid=59&tid=2120860]: |
0ms |
get settings: |
3ms |
get forum list: |
5ms |
check forum access: |
1ms |
check topic access: |
1ms |
track hit: |
56ms |
get topic data: |
3ms |
get forum data: |
1ms |
get page messages: |
792ms |
get tp. blocked users: |
1ms |
others: | 5ms |
total: | 868ms |
0 / 0 |