← All posts tagged ?

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

Захотелось мне объединить 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

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

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

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

Норот, а есть ли какой-нить эффективный способ взять кусочек не из конца и не из начала строки, а из середины по индексам. Речь об Data.Text если чо. Я сейчас использую комбинацию из take и takeEnd.

Так профайлером соптимиздил, однако всё равно фигня получается. Такое ощущение что я неверно с вектором работаю. Есть Unboxed.Vector Word8, мне надо выделить вектор размером 4^12, заполнить нулями, а затем в зависимости от того как часто встречается какая-то из комбинаций увеличивать значение по индексу.
Для создания использую replicate , для обновления accum и в этих местах дохера времени тратиться на выделение памяти.
В в крестиках new на такое количество элементов в инициализацией 0 практически мгновенно...

В Data.Text не нашёл unfoldl. Интересно почему его нет.
Им просто не принято пользоваться?
Проще сделать потом reverse?
Часто генерация не укладывается в unfold и все привыкли использовать явную рекурсию?

Вопрос будет тупой. Есть у меня тип Event

data Event = EEv1 {host :: String, node :: String}
                       | EEv2 {host :: String, node :: String}
                       | EEv3 {fromHost :: String, toHost:: String, node :: String}

Собственно вопрос: многие поля одинаковые. Может есть какие-то более правильные способы такое делать?

Норот, во время тренировки есть необходимость лимитировать интервалы отдыха. 60 сек, 45 сек и т.п. В зале часы есть но ими для этого неудобнопользоваться. Телефон таскать с собой неудобно и опасно для девайса. Хочется недорогой девайс который крепится на руке (a la браслет) или как-то на одежде для замера интервалов.

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

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

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

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

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

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

Есть в fast-logger-е функция flush. Которую надо вызывать перед выходом из программы.
Собственно хочется, что-то вроде сишного atexit, чтоб последние записи в буферах не просрать. От простых исключений мне конечно поможет braket/finalize , а что делать со всякими сигналами или вызовом exit?

Есть у меня несколько функций с типом:
type Foo = ByteString -> IO ()
хочу
type Foo = MonadIO m => ByteString -> m ()

Получаю:
Illegal polymorphic or qualified type:
forall (m :: -> ). MonadIO m => ByteString -> m ()
Perhaps you intended to use -XRankNTypes or -XRank2Types
In the type declaration for `Foo'

Вопрос: доколе!^W Почему оно без этих расширений не получится?

У меня есть некая строка в которой надо заменить некое сочетание, если оно встретится, на строку.
В С я бы взял sprintf ("command -p %s", param); и если будет просто "command" оно ЕМНИП нормально работает.
В хаскеле я нашёл Text.Printf , который возвращает чистый String, но в случае ошибки error-ом бросает эксепшн.
Собственно вопроса 2:
1й как проще произвести подобную замену?
2й как обрабатывать такой ексепшн, если он не в IO монаде вылетает?