← All posts tagged Haskell

dr-Chaos

Люди, а присоветуйте мне структуру данных для хранения лог-а. Вот есть в RaFT-е лог. От него требуется:
1. выдавать запись по индексу (индексы целые монотонновозрастающие)
2. выдавать последнюю запись
3. добавлять запись в конец
4. убирать записи с индексом >= нужного

Сейчас такой лог реализован IntMap-ом в памяти и, вцелом, он неплохо справляется реализуя перечисленное:
1. lookup
2. findMax
3. insert
4. filter

Однако, хочется persistance. Первая идея была взять acid-state и при коммите сохранять IntMap туда. В принципе, можно наверное просто в файл после сериализации сохранять, состояние то между потоками не шарится писать туда может только один... Обновления там простецкие, index++ и дописать в конец. Может кто-то встречал что-то более подходящее или есть какие-то идеи?

dr-Chaos

Хочется все ошибки в процессе разбора документа собрать, а уже потом их выводить. По идее этот код должен подобное делать:
runX (errorMsgCollect >>> xunpickleDocument xpickle [] "foo.xml" >>> getErrorMessages)
но, сука, не делает. Я вот думаю толи я стрелки не так использую, толи вторы библиотеки...

dr-Chaos

Ну что за хуйня!? Есть xunpickleDocument и xpickleDockument. При этом прервая принимает URI который для винды будет /d:/foo/bar.xml , а вторая путь к файлу d:\foo\bar.xml . И нету функции что нормализует путь в ФС к URI.
Ну ёб вашу мать.

dr-Chaos

Вот понятно как работает modifyMVar_ но всё таки что означает приписка в описании:
However, it is only atomic if there are no other producers for this MVar. Ведь всё что находится между takeMVar и putMVar выполняется эксклюзивно.

dr-Chaos

Есть такая задача: через вебсервер wrap приходи запрос. По его приходу должен запуститься асинхронный процесс (добавление/удаление сервера в кластер на RaFT-е) собственно мне нужно дождаться его завершения вполне себе "синхронно".
Я для этого взял 2 MVar-а. Собственно MVar можно воспринимать как однонаправленный канал (message box), в итоге получается я сделал что-то вроде двунаправленного канала.
Собственно вопрос: встречался ли кто с подобными готовыми примитивами?
ЗЫ готов выслушать предложения как эту задачу решить иначе.

dr-Chaos

Захотелось мне объединить 2 монадных транформера в один. В итоге я не могу написать дефолтную реализацию для MonadTransControl, которая нужна для MonadBaseControl.  Точнее я не могу нормально вписать тип в ^1 . По примеру из https://hackage.haskell.org/package/monad-control-0.3.3.0/docs/Control-Monad-Trans-Control.html#g:2

data WebAppState = WebAppState { _configChangeMutex :: MVar ()
                               , _plumbingState :: PlumbingState }
makeLenses ''WebAppState

newtype HandlerT m a = HandlerT { unHandlerT :: ReaderT WebAppState (LoggingT m) a}
    deriving (Monad, MonadReader WebAppState, Applicative, Functor, MonadLogger, MonadBase b )

instance MonadTrans HandlerT where lift = HandlerT . lift . lift

instance MonadTransControl HandlerT where
     newtype StT HandlerT a = StHandler {unStHandler :: StT (ReaderT WebAppState (LoggingT m)) a} -- ^1
     liftWith = defaultLiftWith HandlerT unHandlerT StHandler
     restoreT = defaultRestoreT HandlerT unStHandler

instance MonadBaseControl b m => MonadBaseControl b (HandlerT m) where
    newtype StM (HandlerT m) a = StMHandlerT {unStMHandlerT :: ComposeSt HandlerT m a}
    liftBaseWith = defaultLiftBaseWith StMHandlerT
    restoreM     = defaultRestoreM   unStMHandlerT

Собственно вопрос: как это сделать?

dr-Chaos

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

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