to post messages and comments.

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

Продолжая вопросы из — #2794212 . Собственно расставлением кучи ! мне удалось заставить вылетать эксепшн в нужном потоке. Однако, мне нифига не понравилась такая т.к. мне кажется это совсем не правильным. Т.е. sink по умолчанию ленивый по своим агрументам, и только после того как я сделал его энегричным, что-то заработало.
Собственно встаёт вопрос как принято решать в кондуитах проблемы с тем что санк с эксепшеном может улететь в другой поток?
Кроме того можно, же воспользоваться decodeOrFail . Но насколько я понимаю тогда придётся воспользоваться map Maybe (...) $$ catMaybe $$ sink . Но информация об ошибке пропадает. Чтоб не пропадала придётся писать свой Conduit.

Есть у меня RollingQueue привязанная к UDP сокету. И если в сокет записать херню вылетает эксепшн из Binary десериализатора. Но обрабатывается он совсем не там где я ожидаю. Код тут:
gist.github.com
Подскажите почему так происходит.

Есть у меня необходимость принимать по UDP пакеты. Выглядит сейчас это - так:
CNU.sourceSocket sock 4096  $= CL.map CNU.msgData
                                    =$= conduitDecode 
                                    =$= CL.map (uncurry EMessage)
                                    $$  CRQ.sinkRollingQueue  q

Принимается пакет, потом десериализуется, а затем суётся в очередь.
Собственно, если данные превышают размер пакета они собираются из нескольких пакетов при этом sender из UDP-шного пакета игнорируется. Тут остаётся актуальным вопрос переупорядочивания UDP-ишных пакетов, т.е. если я засуну в сокет больше 4096 с одной стороны, то на приёмнике могу получить что-то вклинившееся между этими 2-мя пакетами или это просто влияет на размер буфера? 
Сейчас появилась необходимость скомбинировать адресс/порт отправителя  с десериализованным сообщением, учитывая что сообщение может быть разбито на несколько пакетов... Хочется для этого како-то zipConduit использовать, но что-то не очень понимаю как. Собственно помогите с примером.

Например у меня есть некий кондуит, который получает по UDP пакеты, преобразует их в нужный мне ADT и пихает в очередь. Выглядит запуск примерно так:

void $ forkIO $ sourceSocket sock 4096 =$= ... =$= sinkRollingQueue

И вот пришло нам битое сообщение из-за него вылетает эксепшн, но я не хочу прибивать весь процесс к чертям из-за такой мелочи. Собственно первое что приходит на ум — это отловить эксепшн с пом onException, вывести в лог сообщение об ошибке и снова запустить кондуит, как-то так:

getMsg =  sourceSocket sock 4096 =$= ... =$= sinkRollingQueue

void $ forkIO $ getMsg `onException` (\e -> print e >> getMsg) 

Собственно вопрос - это обычно так и делается или я что-то упускаю?

А что если собирать трубу кондуитов с помощью стрелок? Это вообще возможно? Уж покуда кондуит имеет входной тип, выходной тип, и возвращаемый тип, то можно же иметь комбинаторы, превращающие кондуит в стрелку, где входной тип стрелки соответствует входному типу кондуита, а выходной тип стрелки соответственно выходноый тип кондуита, правда не понятно как быть с возвращаемым типом, возможно последняя стрелка должна просто свой результат биндить с возвратом кондуита, а не с его выходом.
Как идея? Подводные камни?

Смотр, жуик, у меня есть конструктор сурсов, например такой
createSourceA :: a -> Source m b
Я хочу создать другой сурс, который будет внутри создавать соурсы с помощью createSourceA и скармливать их на выход, естественно, до определенного условия выхода.
Как ?

Итак есть задача. Проксировать файл по HTTP с проверкой HMAC .
gist.github.com
Есть функция saveAndVerifyBody . Она берёт source и скармливает его 2-м zip-нутым синкам. Один из которых считает HMAC, а 2й записывает по временный файл.
Собственно, хочется сохранять не в файл а отправлять по HTTP дальше. Однако, как-то нормально это не придумывается, т.к. Request принимает как аргумент только Source :( Я пока пришёл только к схеме из функции saveAndVerifyBodyHttp .
Может вы чего подскажете?

Господа, есть вопрос по кондуитам.
Я хочу доработать биндинги для memcached-а. И одна из идей была использовать conduit-ы. И как я сейчас понимаю для этой задачи source/sink не особо то и нужны (т.е. обработка чанками в константной памяти конечно прикольно, однако в моём случае я всегда знаю размер), с другй стороны в yesod-е всё в resourceT и будет освобождение ресурсов в случае ексепшена.
Собственно вопрос, какие есть альтенативы и есть ли они вообще.

итак, мне хочется довольно странной вещи иметь буфферизуемый кондуит, который может проверять есть ли возможность пропихнуть данные в downstream и если нельзя, то продолжать брать данные из upstream. Для чего это мне нужно: хочется чтобы поток не простаивал на ожидании ресурса (возможности писать в сеть). Сложности: если данные из апстрима приходят редко, то можно попасть в ситуацию, когда поток висит ожидая этих данных, т.е. в этом случае хотелось бы иметь некий tryAwait/tryYield. Вопрос действительно ли это странно? возможно ли что это переусложнение на ровном месте? и как это можно реализовать?

Я вижу вариант с IORef: каждый поток атомарно его лочит, и использует ресурс, если ресурс залочен — возвращается к upstream. Этот вариант абсолютно не устойчив к недостатку данных из апстрима, плюс может привести к тому, что один из потоков не будет давать другому писать в ресурс. Первое обходится только гарантией того, что в апстриме будут данные, второе проверкой размера буффера, но это костыли.

Можно делать TMVar на апстрим и даунстрим, тогда не будет перечисленных выше проблем, но придется вводить поток, который будет отмечать готовность апстрима..

В общем мрак какой-то...

а это правильная реализация andThen? gist.github.com в смысле мне в "юзерском" потоке иногда надо вылавливать определенные события, в остальных случаях события должны уходить в /dev/null

Кто вкурил, что такое кондуиты и зачем они нужны? Я сколько ни читаю Сноймана, не могу уловить принципиального отличия от ленивых списков.

я правильно понял, что кондуиты — это возможность писать на хаскеле как на энергичном языке, фактически полностью в неком энергичном IO + освобождение ресурсов ?

похоже настало время задать этот вопрос. Iteratee ? Counduit ? Что лучше / хуже ? Зачем нужно уже понял.
Короче годных мануалов и всего такого реквестирую

посмотрел тут на html-conduit+dom-selector — Text и всё такое, но стрелки из hxt как-то всё-равно понятней для выборок сложней однострочников аля xpath

вроде тупая задача — получить файл по http и path из последнего запроса (ибо могут быть редиректы) — а считай за целый день так и не смог составить матрёшку из ResourceT и прочих IO

принимаются идеи как реализовать функицю mergeSources :: (Monad m) => [Source m a] -> Source m a, которая по очереди тянет данные из источника и закрывает трубу если правая часть выполнена

не охота сразу в кафе писать так что может тут попробую.
есть поток данных из conduit [A|B], который нужно писать в несколько файлов, т.е. приходит событие A я начинаю создавать файл под него и писать
нужные события B в него; при этом одновременно запись может идти в несколько файлов. Вопрос в том, как это аккуратно реализовать, я вижу несколько вариантов:
1). сделать тупой sink который будет собирать все данные и выдавать результирующую структуру: минусы нифига не conduit-way, пользуется дофига оперативки,
программа будет выглядеть как лапша
2). воспользоваться stm-conduit и под каждый новый файл создавать канал, в который писать из sink-куда приходят данные и закрывать его, при необходимости,
плюсы: простое слежение за ресурсами, программа будет сильно понятнее, минусы неоправданное использование stm (есть реализация на IO-Channels, но она пока не
до конца рабочая)
3). можно-(ли?) создавать недовыполненный Pipe для записи в файл и в sink-е писать в соотвествующую трубу, тут интересный момент, что оно действие получается
недовыполненым: плюсы используется минимум лишних сущностей, минусы я не знаю как это правильно реализовать