voidlizard.online
117 subscribers
160 photos
6 videos
5 files
105 links
Haskell, распределённые системы.

Разработка P2P CAS hbs2 и приложений для него

Распределенный git aka hbs2-git

hbs2.net

Прочее https://t.me/genedrd47r (мото, EUC, скайдайвинг, дайвинг)
Download Telegram
#offgrid Допустим, pull request это просто сообщение, в котором указано, где майнтейнеру взять изменения, которые смержить к себе. интересно,
как определять, что PR действительно смержен. Наличие коммита(ов) из PR на мастере(мастере?) ? Нет, ведь мейнтейнер мог сделать merge —squash —no-commit и взять всё одним коммитом. Наличием tree объекта на мастере (мастере?) идентичного тому tree, для которого делался PR? Ближе. Но на предыдущем шаге майнтенер мог добавить каких-то своих файлов, но делают так редко. Ок, допустим, наличие на мастере (мастере?) tree объекта, в который входят все блобы из tree объекта коммита PR. Хотя он майнтейнер в процессе мержа мог файлы не менять, а перетасовать их по каталогам, но обычно так не делают. Ну допустим, с некоторыми натяжками можно. Теперь про мастер. Всё еще смешнее. Название бранча в гите - это просто название файла в .git/refs/heads. Оно может совершенно произвольно меняться и это никак не трекается в самом гите. Но трекается в offgrid-git в силу его природы.

Таким образом, критерием приёмки PR можно считать тот факт, что в топике (репозитории), куда направлялся данный PR, существует commit, которому предшествует commit на который делался PR, и существует бранч, имя которого совпадает с тем, который указан в PR (допустим, master) и который существовал в какой-то момент после создания PR (это значит. что существует reference, name = master и в зависимостях того reference есть коммит, на который делался PR). Если всё это выполняется, можно сказать, что PR смержен. Наверное.
Пришла в голову мысль, что если скрипты создания базы развернуть в поток операций создания колонок ( ALTER TABLE X ADD COLUMN ... ); - то каждую такую операцию легко сделать идемпотентной, а процедуру миграции базы - тривиальной и вообще она типа становится CRDT но это не точно
Что-то я застрял с sql-ным dsl-е. Первоначальная идея была сделать маленький слой над sqlite-simple, что бы не писать руками бесконечные примитивные - запросы - сделать простой DSL для генерации.

DSL сделать на уровне типов, что бы интерпретаторы писать тайпклассами - ну, примерно, как в серванте. До определенной стадии получилось, особенно нравится то, что не нужно, как в persistent описывать "таблицы" - а только те поля, которые используешь завернуть в newtype и задать для них колонку таблицы через тайпкласс.

Для простых запросов работает отлично. Для постгреса этого и хватает - любой сложный запрос это, считай, view - pg отлично работает с view + это даёт еще дополнительных плюшек.

Для sqlite лучше бы уметь делать вложенные запросы - и как-то это надо уже композить на уровне типов. В sql-ных запросах полно опциональных вещей, и как вот их подпихнуть в ту конструкцию, что тут на картинке (в коменте, в пост не влезло)?

Оно мало того, что позволяет разные запросы разбирать разными тайпклассами, так оно еще и типизирует и колонки запроса, и возвращаемое значение. Бойлерплейта для простых запросов получается мало и вообще прослойка над raw sql получается очень тонкая.

Но не понимаю, как хорошо сделать этот DSL расширяемым. Добавить туда всякие там limit, order, group by и так далее.

К моноидальным и монадическим DSL здесь не хочется скатываться, получится очень шумно + некорректно. Но как сделать нормально не пойму.

Очень не хочется тащить в проект persistent, слишком много там всего ненужного делается. beam вообще шляпа какая-то. #haskell #sql #edsl
При сдаче проекта неожиданно отлично работает скринкаст, который ходит и демонстрирует все фичи, особенно, если около каждой фичи в списке указать её таймкод в скринкасте.
Во первых - его никто не смотрит! Но он есть и внушает уверенность. Во вторых - по хорошему, его бы генерить автоматически каким-нибудь селениумом.
Тесты такие все равно нужны, а тут только запуск скринкаста приделать. По скрипту на фичу, а потом в один видос слить. Не, но то, что их не смотрят это прям лол. Софт принимать это вам не языком в зуме чесать.
Каждый раз, когда начинаешь что-то делать, задаёшься вопросом, а как там будут виндовые пользователи. Реально, как про лиц с ограниченными возможностями ради повышения инклюзивности. Под линуксом-то, понятно, всё будет работать и всё есть. На маке тоже как-нибудь завёдется. А что делать виндовым пользователям? Надо, что бы и у них как-то работало. Давайте добавим ручки в протокол, что бы могли ремотный хост использовать в качестве костыля
Offgrid жив, просто все занимает больше времени, чем хочется. Писать новости сломанной рукой непросто. Ищем финансирование потихоньку
#offgrid На этой неделе начнём тестировать криптоподписку: ограничение на чтение/запись при помощи криптографических механизмов. Обратная совместимость поломана, всё внешнее поломано, но после фиксации изменений можно будет чинить и потом делать, например, приватные репозитории offgrid-git или же чатики, а то до этого момента всё было только открытое. Довольно сложная история оказалась, неудивительно, что мало кто это реализует
купил неттопчик для работы и для будущей ноды офгрида, что бы не шумел. завис на выборе файловой системы. точнее, даже так - хочу сделать типовой конфиг для рабочей машики, что бы потом быстро раскатывать. завис на вопросах: zfs или btrfs ? хочется постепенно настроить инкрементальные бэкапы чего нужно, а что не нужно - не бэкапить. шифрование чего нужно - а что не нужно не шифровать. т.к. будет много компилировать - весь хомяк или весь диск шифровать не хочется. если я правильно понимаю, то на блочном уровне zfs сможет шифровать отдельные под-тома, а btrfs - только работать поверх шифрованного устройства. следовательно, бэкапы btrfs-ных томов будут не зашифрованы. с другой стороны, zfs любит память и по бенчмаркам - от двух до трёх раз тормознее. что же взять?

UPD. еще у меня то, что мне важно живет в syncthing и в git, а что там не живёт - то мне и не нужно. таким образом, инкрементальные бэкапы на уровне томов мне особо-то и не нужны были. система же под nixos и так особо не ломается, а если ломалась - то 1) собственными моими усилиями 2) легко чинилось при помощи текстового редактора. т.е time machie-то мне особо и ни к чему

UPD2. если бы не шифрование, то и вопросов бы никаких не было - взял бы btrfs

UPD3. а если бы не сведения, что zfs тормознее и память любит - взял бы просто zfs
запилил повторяемый конфиг системы на nix flakes для нового десктопчика, xmonad + polybar + никсифицированный nvim c плагинами. Говорят, красота спасёт мир, на самом деле, она его сожжёт дотла. Если даже не вспоминать троянскую войну, то что бы добиться красивой панельки, которая в mate дичайше глючила c xmonad - портились иконки - пришлось эту панель из mate выкинуть нафиг и вкрутить polybar. Только на то, что бы заставить телеграм отображать приемлемую иконку для темного трея - ушло часа полтора с strace. Знаю теперь много про то, как работает иксовый десктоп, кто на ком стоял и через что сообщениями обменивается. Лучше бы не знал. Зато прикрутил к xmonad-у haskell-language-server и подружил это всё с home-manager+flakes, теперь хоть жить можно. Сука ладно, а в троянской войне вообще люди погибли и одна из возможных причин катастрофы бронзового века. Так что два дня гребли с конфигами это фигня. Зато по nix level up, начинаю его понимать, через три года использования.
#offgrid кажется, у нас подъехала более-менее стабильная версия ноды с шифрованием и можно начинать туда перекладывать исходники. При этом так же кажется, что для того, что бы это начало кого-то впечатлять, надо приделать какой-никакой gui и выложить с публичной нодой в большом интернете (и посмотреть, загнётся или нет). С другой стороны, очевидно, что без специальной обёртки для хайлоада загнётся - вся суть распределенности в том, что бы нагрузка распределялась по группам, а не все бежали в одну ноду.
С другой стороны - без публичной ноды на первом этапе - никто ничего не заметит. Вот, есть sourcehut, куда народ с гитхаба побежал. Так вот там самый-самый базовый ui на коленке - и ничего - они уже за это берут плату это раз, и оно удостоилось отдельного протокола в nix - это два.
#haskell смотрите, что нашел: json-stream, аппликативный парсер для json. в частности, позволяет избавиться от aeson-овых
портянок описания всех структур данных, из которых нам нужны пара полей, допустим. Например:
-- q - огромная вложенная портянка json-овых объектов с кучей полей
-- описывать такое на aeson, все (ненужные) промежуточные типы,
-- инстансы, маппинг полей - просто вскрыться.
-- тут же такое:
q = ...
fixed = realToFrac <$> number
pquo = "quote" .: "USD" .: "price" .: number
parseByteString ( "data" .: "BTC" .: arrayOf ( (,) <$> "symbol" .: string <*> pquo ) )

[("BTC",16825.237237370766)]

просто прекрасно, я считаю. даже линзы намного муторнее, не говоря о том,
что там надо разбирать всю структуру в память, чего здесь нет
#offgrid #offgridgit починили offgrid-git для работы с ... multipart сообщениями. шифрованные топики пока не пробовали.

upstream: offgrid://6d8DHjfiCKAmEGyBG7CD5AkPz8y1kBmL485PKa6Azey7

надеюсь, ломающих изменений больше не будет
Лемма: несмотря на наличие лёгких потоков, в программе должно быть O(1) потоков, иначе вам жопа (_|_) TBD: нужно математическую нотацию для "вам жопа"
Следствие: компиляторы нужно объединить с пруф-оф-ворк блокчейнами, и на каждый forkIO в программе требовать доказательство работы, например, на велотренажёре. Без этого программа не должна компилироваться
Из nix мы знаем, на что похожи dsl на чистом функциональном языке без монад. на говно. а еще мы узнаем, что синтаксис важен. и лучше отсутствие синтаксиса в виде скобок, чем неудачный синтаксис.
два страха - что дисковые операции дырку в ssd сделают, и что хэши по кругу пойдут. не могу я поверить, что можно спокойно генерить 256-битные хэши и их еще много останется
Посоветуйте, что взять для стриминга? мне надо такое - что бы жило на O(1) по памяти точно и было с минимальными зависимостями и не пыталось свою вселенную построить, как кондуиты. взял было list-t - он протёк, на больших файлах крашится. Тупой пример, чего мне надо - который не падает: https://gist.github.com/voidlizard/46d1bac04f67ed0fd92560817b349b9e - хаскель курильщика, но работает за O(1) по памяти
#haskell читал из файла чанки / защитил докторскую
издохло мгновенно. быстрее, чем всё до того. вот так стриминг! #haskell #streaming #специальнаяолимпиада
Forwarded from Dmitry Zuikov
main :: IO ()
main = do
hSetBuffering stdin NoBuffering

let bebe = Handle.read @IO
qq <- Stream.unfold bebe stdin
& Stream.chunksOf (256 * 1024) Fold.toList
& fmap (hashObject . B.pack)
& Stream.toList

print (length qq)
Вообще я не планировал специальную олимпиаду, я чем-то другим хотел сегодня заниматься. Но по итогам хочу сказать, что рассчёт хэшей файла ~10G на streamly - взрывается. на list-t - взрывается. на unsafeMMapFile - хочет взорваться не но успевает, дорабатывает. на streaming - не взрывается. https://github.com/voidlizard/streaming-wtf/blob/master/MerkleStreaming.hs - работает ~ O(1). ну конечно не O(1) , но пропорционально количеству хэшей * размер хэша, фигня, типа мегабайт на 10 гигабайт. я вообще не этим собирался заниматься. очент досадно за list-t - прикольный и сука бесполезный в итоге