Entry tags:
Clojure, ленивость и отложенные отчеты
Очередной раз стукнулся об ленивость.
Делаю фоновый расчет отчетов - клиент просит у сервиса "посчитай мне отчет", тот ему возвращает идентификатор-ссылку на future со считалкой отчета и далее клиент опрашивает сервис на предмет "а не готов ли наш отчет" и тот ему отвечает либо "не готов" либо "готов, вот тебе данные".
Ну, склепал очередь отчетов - атом, в нем мап, в мапе идентификаторы запрошенных отчетов и future к ним. Запускаю - а оно мгновенно говорит, "да, вот отчет готов, забирай" и давай его считать и отдавать. В потоке запроса, не в рабочем потоке future.
Ленивость. Оно возвращает башку последовательности данных отчета сразу, "на тэбэ, дорогой, форси меня". И запрос готовых данных (в том числе, даже просто попытка в целях отладки посмотреть на мап с future) - вызывает форсинг последовательности.
PS: И еще обнаружил очередную фичу кложури - thread-local bindings протаскиваются во все вызовы, которые перекладывают работу в другие потоки. Т.е. конкретно тут - я в запросе часть общих параметров (типа имени пользователя) складываю в thread-local binding чтобы не протаскивать их руками через 100500 функций, думал, что при вычислении внутри future придется их доставать и перекладывать во второй поток - а оно уже сделано.
Авторы кложури не перестают удивлять своей крайней адекватностью и практичностью языка.
Делаю фоновый расчет отчетов - клиент просит у сервиса "посчитай мне отчет", тот ему возвращает идентификатор-ссылку на future со считалкой отчета и далее клиент опрашивает сервис на предмет "а не готов ли наш отчет" и тот ему отвечает либо "не готов" либо "готов, вот тебе данные".
Ну, склепал очередь отчетов - атом, в нем мап, в мапе идентификаторы запрошенных отчетов и future к ним. Запускаю - а оно мгновенно говорит, "да, вот отчет готов, забирай" и давай его считать и отдавать. В потоке запроса, не в рабочем потоке future.
Ленивость. Оно возвращает башку последовательности данных отчета сразу, "на тэбэ, дорогой, форси меня". И запрос готовых данных (в том числе, даже просто попытка в целях отладки посмотреть на мап с future) - вызывает форсинг последовательности.
PS: И еще обнаружил очередную фичу кложури - thread-local bindings протаскиваются во все вызовы, которые перекладывают работу в другие потоки. Т.е. конкретно тут - я в запросе часть общих параметров (типа имени пользователя) складываю в thread-local binding чтобы не протаскивать их руками через 100500 функций, думал, что при вычислении внутри future придется их доставать и перекладывать во второй поток - а оно уже сделано.
Авторы кложури не перестают удивлять своей крайней адекватностью и практичностью языка.
no subject
Правда, у бд есть преимущество - курсоры, в отличие от ленивых вычислений, будут более-менее согласованны; и согласованность эту можно задавать.
Впрочем, тут на это, как я понимаю, в общем, наплевать.
no subject
С согласованностью у кложури свои заморочки, у нее есть встроенная транзакционная память и тому подобные чудеса, но я ее не использую, т.к. все интересующее меня состояние живет в БД и транзакции с уровнем изоляции snapshot вроде нужный уровень согласованности гарантируют.
no subject
Ну почему не фетчится. Фетчится, только медленно.
no subject
no subject
no subject
no subject
Два селект топа каждый раз, или тянут всё на клиент и перекладывают на грид, или что-то промежуточное, вроде "посчитали конечную табличку, оставили на сервере, по мере листания на клиенте получаем из неё куски"?
no subject
Меня огорчает мысль о том, что этот запрос выполняется повторно на каждую страницу, поэтому теоретически, надо бы выполнить его один раз и закэшировать.
no subject
Кстати, интернет-поисковики как раз перевыполняют запросы каждый раз при листании серпа, кэшировать им получается сложнее. При этом, что интересно, чем дальше листать, тем им технически печальней -- яндекс, например, принципиально дальше сотой страницы не пускает, даже если десять миллионов результатов найдено.
no subject
no subject
no subject
no subject
А для динамических нужны какие-то более другие методы работы, в т.ч. и кэширование результата запроса.
no subject
Пейджинг собственно только для того и нужен, чтобы особо недоверчивые были уверены что они "проверили всё глазками".
(no subject)
(no subject)
(no subject)
(no subject)
no subject
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
no subject
кложа - для нормальных людей. скалы, жсы и прочие груви - для ортурегов и ждевелопов.
no subject
no subject
no subject
Т.е. в общем виде проблема в том, что мы считаем стейт на основе предыдущего много раз, и хз когда он нам и в каком виде потребуется. Если у нас нет лени - мы просто жарим CPU, и если он успевает - все ок. А с ленью всплывают интересные философские вопросы.
Как такое чинить в общем виде в хаскеле - не ясно. Мне хватило зафорсить один санк, это почему-то вылечило stack overflow, но стейт до текущего времени при разворачивании окна оно все равно догоняет, для меня это уже не критично было.
no subject
no subject
да какие там вопросы -- сплошные ответы. С ленью в этом случае сначала жарим память, откладывая личинки вычислений, а только потом жарим совместно память, цпу и бедного мусорщика. Причём цпу обычно жарим на большее количество тактов -- надо же эту лентяйку обслуживать как-то: смотреть, посчитали личинку или ещё нет, например.
Выгода тут есть только тогда, когда многие вычисления не нужны. Но при гуе навряд ли так выйдет.
no subject
no subject
А разве 1.3 это недавно? Я вроде 1.4 год назад начал использовать, 1.5 недавно вышла.
no subject