metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2013-03-26 09:25 pm
Entry tags:

Clojure, ленивость и отложенные отчеты

Очередной раз стукнулся об ленивость.

Делаю фоновый расчет отчетов - клиент просит у сервиса "посчитай мне отчет", тот ему возвращает идентификатор-ссылку на future со считалкой отчета и далее клиент опрашивает сервис на предмет "а не готов ли наш отчет" и тот ему отвечает либо "не готов" либо "готов, вот тебе данные".
Ну, склепал очередь отчетов - атом, в нем мап, в мапе идентификаторы запрошенных отчетов и future к ним. Запускаю - а оно мгновенно говорит, "да, вот отчет готов, забирай" и давай его считать и отдавать. В потоке запроса, не в рабочем потоке future.
Ленивость. Оно возвращает башку последовательности данных отчета сразу, "на тэбэ, дорогой, форси меня". И запрос готовых данных (в том числе, даже просто попытка в целях отладки посмотреть на мап с future) - вызывает форсинг последовательности.

PS: И еще обнаружил очередную фичу кложури - thread-local bindings протаскиваются во все вызовы, которые перекладывают работу в другие потоки. Т.е. конкретно тут - я в запросе часть общих параметров (типа имени пользователя) складываю в thread-local binding чтобы не протаскивать их руками через 100500 функций, думал, что при вычислении внутри future придется их доставать и перекладывать во второй поток - а оно уже сделано.
Авторы кложури не перестают удивлять своей крайней адекватностью и практичностью языка.

[identity profile] jakobz.livejournal.com 2013-03-26 09:18 pm (UTC)(link)
А это не то ли IO вперемешку с ленью, с которым борятся монадой в хаскеле? Или у тебя тупо чистые вычисления там, и просто не зафорсилось где надо?

[identity profile] metaclass.livejournal.com 2013-03-26 09:20 pm (UTC)(link)
Оно самое, побочные эффекты+лень.

[identity profile] jakobz.livejournal.com 2013-03-26 10:19 pm (UTC)(link)
У меня похожая прикольная тема была. OpenGL-окошко на хацкеле, стейт в MVar, обновляется в idle на нужное количество тиков по таймеру. Сворачиваешь окошко, разворачиваешь - stack overflow.

Т.е. в общем виде проблема в том, что мы считаем стейт на основе предыдущего много раз, и хз когда он нам и в каком виде потребуется. Если у нас нет лени - мы просто жарим CPU, и если он успевает - все ок. А с ленью всплывают интересные философские вопросы.

Как такое чинить в общем виде в хаскеле - не ясно. Мне хватило зафорсить один санк, это почему-то вылечило stack overflow, но стейт до текущего времени при разворачивании окна оно все равно догоняет, для меня это уже не критично было.

[identity profile] jakobz.livejournal.com 2013-03-26 10:21 pm (UTC)(link)
Вот была бы, скажем, возможность форсить санки в каком-нибудь фоновом idle-процессе. Вероятно была бы интересная модель параллельных вычислений.

[identity profile] gds.livejournal.com 2013-03-26 10:35 pm (UTC)(link)
> Если у нас нет лени - мы просто жарим CPU, и если он успевает - все ок. А с ленью всплывают интересные философские вопросы.

да какие там вопросы -- сплошные ответы. С ленью в этом случае сначала жарим память, откладывая личинки вычислений, а только потом жарим совместно память, цпу и бедного мусорщика. Причём цпу обычно жарим на большее количество тактов -- надо же эту лентяйку обслуживать как-то: смотреть, посчитали личинку или ещё нет, например.
Выгода тут есть только тогда, когда многие вычисления не нужны. Но при гуе навряд ли так выйдет.