elglin: (Default)
Не Дийкстра я ни разу, но хоть примажусь.
В 2016 году к нам прибежал наш внутренний идеолог Амазона и заявил, что еще полгода, и админы будут не нужны. Мы его обсмеяли, а он сейчас большой начальник; я вообще не понимаю, как он сделал карьеру на завале двух эпических проектов, продолбавших шести-, если не семизначную сумму, но вот поэтому он Бенцион Крик, а у меня в душе осень.
Ну кагбе пять лет прошло, воз миграции в Амазон и ныне там, хотя есть шанс, что он с непередаваемым скрипом таки поедет если не в этом, так в начале следующего года.
Но я не об этом. Амазон продвигает свой концепт, что надо убрать undifferentiated heavy lifting и сосредоточиться на бизнес-логике. Естественно, за помянутый heavy lifting надо немного отстегнуть Амазону, что логично. И опять же, суть не в этом, а суть в том, что разработчик в кои-то веки можно полностью контролировать стек. И это прямо-таки офигенно.
Вот я подумал за свой приклад. Да, там, конечно, внизу сервер, пицот лет конфигурять. А если вдуматься, то докерфайл будет не такой и развесистый, особливо если его собирать поэтажно, как доктор прописал. И если у меня есть докер-инфраструктура, которую не я собираю (AWS ECS/Fargate, EKS), то на докерфайле заканчивается моя зона ответственности и начинается зона... сервис-провайдера.
То же самое со всякими файрволами и балансерами (в кубиках это контролируется прямо из кубиков, в ванильном AWS - хоть терраформом, хоть CloudFormation). То же самое даже с мониторилками и логособиралками и далее по тексту.
База... ну формально я к этому постгресу рутовый доступ имею. В реальности катаешь миграции, смотришь диагностику и все такое, так что можно сказать, что и постгрес мне сгодится "как сервис". Туда же пойдет и модный редис, и любые Kafka/RabbitMQ и так далее.

То есть суть в том, что граница ответственности разраба почти везде сомкнулась с границей ответственности сервис-провайдера. Для админа, который жил как раз между этими границами, места нет. Окей, скажете вы, но ведь все эти жабаскрипт-мидлы и решетка-сеньоры ни черта не понимают в архитектуре. Ну, во-первых, понимают порой очень немало, во-вторых, можно вспомнить, что во времена оны человек, подозрительно похожий на современных SRE, назывался системным программистом и на сисопа или админа мог заслуженно оскорбиться.
Конечно, тут можно сказать, что cloud is just other people's servers, но суть в том, что в этом самом Амазоне, к примеру, классической админской работы, мне думается, мало. А за пределами Больших и Толстых провайдеров, мне думается, грядет плавное вымирание мелких и тонких.

Короче, то ли товарисч реально зрил в корень, то ли это был тот самый случай, когда стоящие часы правильное время показывают. Ну и надо понимать, что при всей своей апокалиптичности прогноз очень длинный. Классические админы за 50, а то и за 40, могут успеть уйти на пенсию до того, как прозвонит колокол. А вот тем, кто помоложе, как мне кажется, надо вспомнить про необходимость, которая понимающего ведет, а непонимающего тащит.
elglin: (Default)
Разбираю тут потроха не имеющей аналогов терраформовской кодобазы.
ТОННЫ ДИЧАЙШЕГО ХАРДКОДА.
При этом в лучшем случае абаснуй примерно такой: "Ну это у кого-то когда-то работало, а дальше все копипастили, не задумываясь". В худшем случае нет и этого.
Ну его нахер, ребята, так работать. Но именно так и работаем, потому что человека, который что-то понимает в программировании не на уровне кричания лозунгов DRY, KISS и так далее, а на уровне понимания их, найти сложно. А товарища, который под этими лозунгами будет бездумно копипастить (в кодовой базе около трехсот "почти одинаковых" файлов, из которых выделяется несколько кластеров одного размера, но есть и десятка три "снежинок"), найти очень просто.

Ну и еще. Любой вспомогательный скрипт, с моей точки зрения, должен выдавать машиночитаемый формат. Либо CSV/TSV/DSV, который awk-ается, либо JSON/YAML/TOML/XML (последнее, конечно, не нужно, но можно), который парсится тем же питоном (или jq для адептов баша) и кем только ни. При этом в идеале надо бы выдавать объект языка Х, который только в самом конце превращать в текст, чтобы желающий на том же языке привязаться не извращался конструкциями вида json.loads(json.dumps()). Желающий красивого вывода может написать обертку этого дела с форматированием - классическое отделение данных от представления.
Но нет. Только человекочитаемый вывод в формате, который **нешься парсить, не говоря за грепать.

Радует только одно. Сегодня тяпница, и эликсир узбагоения уже ждет.
elglin: (Default)

15 лет прошло, ничего не поменялось. Ну как, мы все стали старше, и даже pretty girl like you.
elglin: (Default)
Хочется писать хороший код. Продуманный. Отлаженный. Самое главное - хорошо спроектированный.
Проблема только в том, что, обычно, вокруг ходит цейтнот. Причем такой цейтнот, что с той стороны контроль классический, а у тебя блицевый. Тут, увы, не до анализа вариантов в схевенингенском варианте сицилианской защиты.
Это я к тому, что я сегодня осознанно вмерджил к себе кусок совершенно потрясающего говнокода. Задача-то банальная - отсыпать нотифайки в такую-то ручку в таких-то случаях. Проблема в том, что ручка же черт знает где, а поэтому все прелести распределенного программирования налицо.
Короче, я просто вогнал еще одну таблицу, куда эти нотифайки разного рода инсертятся. Потом наговнякал еще один воркер (у меня их с десяток, одним больше, одним меньше), который ходит в эту табличку и пытается слать. SELECT FROM notifications ORDER BY notification_id LIMIT 1 FOR UPDATE; получилось - DELETE FROM notifications WHERE notification_id = XXX; не получилось - а ничего не делаем, на следующем проходе поретраим и так ad infinitum. Да-да, никакого вам ограниченного ретрая с экспоненциальным отступом - ручка будет страдать, один хрен она не моя.
По уму надо тут просто что-то, умеющее pub/sub прикрутить, от кафки до амазоновского SNS. Но у меня был постгрес, приклад с воркерами и час времени, набранный кусками по 15-20 минут.

Вот так и живем, мать его так.
elglin: (Default)
Нимагумалчать.
Нам года полтора ели мозги, ах как у нас замечательно терраформом все в Амазоне разворачивается. Ну я читал Хабр, да, терраформ неплохо.
Ну реально, есть у тебя солидная аппликуха, там, фронтенд, бэкенд, оффлоад статики, CDN, постгрес какой-нибудь с редисом на подхвате, балансер какой-нибудь, причем не один, скорее всего, какие-нибудь очереди или pub-sub и так далее. И вот оно у тебя по одной команде хопа - и развернулось или обновилось, поди плохо.
Давайте начнем с чего-то простого, предложил я. Давайте вы покажете, как нам развернуть голый линукс. Обычный, без изысков. Вот вы говорите, что у вас модуль есть. Далее разные отрывки из диалога, самая мякотка.
Э(ксперты): надо взять последнюю версию модуля.
Я: Какая стабильная? Вот у вас есть всякие.
Э: 1.3.8, кажется. Ну посмотри, с какой тут во-он те чуваки что-то делали.
Я: 1.2.0.
Э: Хм... странно.. ну все равно давайте 1.3.8
Я: А я вот тут видел сборки на 1.0.0, они не сломаются, если пересобрать инфру захотят?
Э: Ну мы ж 1.4.0 еще не выкатили, обратную совместимость мы только в нем ломаем, так что пока что не сломаются.
Я: Что-то тут дохрена файлов надо писать. А у вас нет какого-то скрипта, который на автомате генерит болванку?
Э: Ну ваще-то нет, это в светлом будущем [полтора года, напоминаю, они этим хвастаются]. О, точно, у нас тут где-то примерная папочка с файлами есть. Щас найдем.
Я: А как я должен был догадаться?
Э: Ну вот мы тебе только что сказали!
Я: Вот тут нужен идентификатор AMI, где мне его искать?
Э: Ну тебе же RHEL нужен? Ну поищи rhel по репозиторию, мы всегда так делаем, идентификатор обязательно найдется.
Я: А вот этот параметр, если не нужен, его можно убрать или надо, чтобы он был, но занулить?
Э: Ваще-то можно убрать, наверное, но хз, давай занулим.
Я: А если два сервера надо, то можно просто массив переменных фигануть вместо одного комплекта?
Э: Нет, тут надо отдельную папочку на каждый сервер со своим набором файлов.
Я: А на Security Group тоже отдельную папку?
Э: Ну да... только в одном пулле этого делать не надо, потому что порядок обхода папок недетерминированный, и оно может попытаться собрать инстанс до security group и обломаться.

Ах да, самая мякотка. Эти люди (вот эти самые, у которых нужно на каждый чих папочку с полудюжиной почти одинаковых файлов делать) любят в меня тыкать принципом... Don't Repeat Yourself. Но мы же не повторяемся, мы просто копипастим папочки с кодом из одной папочки в другую.
Занавес.
elglin: (Default)
Мне несколько раз с интервалом от месяцев до лет снился сон на одну и ту же тему, что я второй раз учусь у себя на факе. При этом я осознаю, что учусь второй раз, и, вроде как, непонятно, зачем, но вот учусь. Ну и мысли (все во сне), что как же я сессию сдавать буду, у меня же работа, отпрашиваться надо будет и все такое.
Это я, собственно, к чему. Есть некая девочка, назовем ее Х. (нет, не Хуанита). Девочка учится на программистском факультете. Девочке я до того пытался нести в мозг матан и алгебру, их она сдала.
А вот теперь она попросила помочь с пересдачей по погромированию. Я сначала машинально (девочка позвонила аккурат между двумя нервными совещаниями) попросил прислать все задачи и вопросы, и только потом отметил, что на дворе не то, что февраль, а середина его, и сессия закончилась не только сама, но и вместе с пересдачами. Сталбыть, девочка не то, что с хвостом, а в одном шаге от пресловутого компота.
Ну ладно, слава яйцам, у нее не Паскаль, который я бы без методички не вспомнил (хотя у меня на нем написан один курсач - не мой, и одна лаба - не моя), а старый добрый Це. Ну на Це мы могем, и у нас, естественно, есть муха гэцеце (прольем скупую слезу над безвременно почившим ваткомом, а какой был в свои годы компилятор, какой был слон, какой был слон).
Понятное дело, что ничего эпичного там не было - немного очень простой строковой работы, набившие оскомину фибоначчи и немного работы со связным списком и деревьями (рекурсия, омномном). Ну, короче, один вечер после реально упоротой трудовой недели - могу, значит, еще, на первом курсе учиться.
Девочка то ли гнет дерево не по себе, то ли не познала мантру, что ИТ - это ноулайферство, но в консерватории надо что-то менять. Не мое, впрочем, дело ее жизни учить.

Но фиг с ней, с девочкой, там был интересный вопрос, который я в полубессознанке сделал через жопу, а хотелось красиво. Есть у нас два отсортированных бинарных дерева, нам надо найти мощность пересечения, и нам даже гарантируют, что элементы внутри каждого дерева уникальны.
Вариант через жопу - это пройти одно дерево насквозь и поискать каждый элемент в другом. Были бы это два массива, я бы параллельно по ним прошелся и за один проход все нашел.
Но это деревья, и по условиям задачи (структура данных задана жестко) указателя вверх у нас нет, только налево и направо. В этой ситуации я знаю, как сделать параллельный обход, имея два стека. Но у меня не плюсы, где я взял бы стек из STL и горя не знал, а голая сишка. Писать на автопилоте динамический стек поверх связного списка - ну, это так себе затея в первом часу ночи.
А есть ли более кошерный вариант? Теория-то уверенно говорит, что дерево в глубину без стека не обходится.

Надумал я сейчас только извращенный вариант провязывать стек вызовов указателями (чтобы невозбранно ходить в предыдущие стекфреймы), глубину стека держать как максимум глубин погружения в оба дерева - по сути, эмулируя второй стек на стеке вызовов. При этом что при погружении, что при разматывании то и дело придется "переключать" реальный и эмулируемый стеки. Как-то слишком сложно и кулхацкерски.
elglin: (Default)
У меня есть вопрос в пространство по дизайну.
Как бы кошерный способ использовать темплейты контента (в моем случае jinja2) - это держать их в папочке и подгружать через FileSystemLoader. Но вот у меня есть интерфейс поделия из даже не десятка страниц, то есть менее десяти темплейтов, каждый из которых не весит и экран текста (никакого новомодного трэша, старый добрый голый HTML).
Вот насколько допустимым в приличном обществе считается в этом случае тупо грузануть все темплейты при старте приложения и держать их в памяти?
Очевидный минус, не считая жора памяти, - что при смене темплейта требуется перестартовать сервис; с другой стороны, при заданной надежности (90% хватит за глаза) приклад можно хоть с нуля каждый раз деплоить, так что это не проблема в контексте задачи.

Fizzbuzz

Dec. 10th, 2020 06:33 pm
elglin: (Default)
Сегодня на собесе человек с плюсАми в резюме запоролся на сабже. Не, я понимаю, что на заборе тоже написано, а там доски.
Но я вслед за товарищем Спольским считаю, что практикующий программист должен на своем активном языке физзбазз написать за пару минут. Окей, за пять минут, из которых три он будет пытаться понять, зачем его заставили писать эту фигню.
Но не пишут же! Путаются в if-ах. Не могут написать цикл (!). И вот при этом люди рассказывают про то, что в анамнезе было дописывание чего-то на дельфи, или какая веб-приложенька или еще что. И вряд ли брешут.

Вот я и думаю, прав ли я со своим физзбаззом. С одной стороны, любой человек, умеющий придумать и запрогать алгоритм, должен суметь в физзбазз. Но, может, сейчас это уже излишне? Может, стоит попуститься и не мучать людей задачей на один цикл и три if-а? Может, сейчас уже всякие фреймворки дошли до того, что можно писать годный работающий код и вообще не мучаться вопросом, как что-то сделать?
С другой вот стороны, как только ты начинаешь решать какую-то задачу сложнее, чем "пять строчек шелла", то у тебя сразу начинают вылезать конечные автоматы, очереди, графы, структуры данных и вся прочая унылая, но нужная теория из соответствующих курсов. Помню, было очень обидно изобрести jump table чуть раньше, чем про нее прочитал.
Вот и сижу я такой умный в когнитивном диссонансе.
elglin: (Default)
Что-то меня потянуло на философию в последнее время.
Вот у нас есть условный поток "заказов", который к нам приходит, мы каждый пережевываем через несколько состояний этапов так, что он доходит до терминального состояния конца обработки либо сваливается в ошибку. Ну чистый конечный автомат. Совершенно легко кодится в лоб в базе путем добавления поля состояния (integer или text, кому как нравится) в табличку. Как-то совсем олдскульно, в Амазоне вот Step Functions для этого запилили. Вот для очередей, знаю, Kafka есть, а для этого что?
Решил порефакторить код, он начал валиться на ON CONFLICT UPDATE. Врубил отладочные печати, проглядел все глаза, все правильно, с синтаксисом все окей. Оказалось, что в девятом постгресе этого еще не было. Долго думал, откуда я в модном и современном своем поделии взял девятый постгрес. Конечно, придумал, но было очень обидно. Вот прям очень. Более всего обидно, что в продакшене десятка.
В рабочем чате предложил попробовать определить, что есть "приложение" и "сервис". Не то, чтобы обсмеяли, но около того. Наверное, все должно быть придумано до нас, но почему весь наш официальный штат разрабов, аналитиков и девопсов не знает? Осознал, что никто в конторе, судя по всему, никогда не заботился вопросом формального критерия (ну как критерий Коши) того, стоит приклад или лежит. Может, поэтому у нас такой бардак с мониторингом - то есть все, вроде бы, мониторится, и даже алерты летают, но все равно непонятно, что где валяется, и когда все это кончится.
Полчаса терли с коллегой за схематизированную и несхематизированную базу. Сначала почти договорились, что давайте будем модно и молодежно, пусть у нас джейсонка будет. Потом взяли листочек, начали прикидывать, какие поля где точно будут, и как селекты будут выглядеть. В итоге сошлись на олдскульной схематизации. Полное ощущение, что вот сейчас у нас модно и молодежно делать NoSQL, а тут сидят два мастодонта и рисуют таблицу по 3НФ, которая была популярна, когда они в школу ходили. Уже опосля подумал, что совершенно зря у меня в паре таблиц искусственный pkey, надо было естественный сооружать, но надо уже много всего рефакторить, чтобы переделать, от этого совсем загрустил. Толком не отрелизились, а уже обросли легаси, а все от наколеночности и бестолковости.
И вообще полное ощущение сибирского лесоруба, валящего лес топором при наличии японской бензопилы. По сути, модного и молодежного в поделии только питоновская асинхронщина, сделанная, что греха таить, чтобы эту самую асинхронщину руками потрогать, по сути-то там flask+requests хватило бы за глаза. Вебморда у нас голый HTML даже без стилей, она и в lynx-е будет хорошо смотреться, база у нас кондовый постгрес с жесткой схематизацией всех полей, по которым фильтры идут (у нас даже поля JSON, а не JSONB, чтобы не было соблазна лазить в портяночку), да и вместо контейнеров у нас systemd+venv. Короче, лет двадцать назад это писали бы почти так же, ну и где здесь, ети его, прогресс?
elglin: (Default)
В длинных спорах о том "каким ЯП учить в самом начале" с большим отрывом лидируют концепты "меня так учили" и "я на этом прогаю". Есть еще распиаренная лурком цитата: "Хороший программист обязан знать C". Попробую выпрыгнуть из этого концепта.
Итак, первый язык. Товарищи, на каждого рафинированного программера (вроде большей части дискутирующих) наберется пяток людей вроде меня, которые активно прогают, но далеко не рафинированные программеры, и десятка полтора-два людей, которым надо прогать, но от случая к случаю, как приложение к основной работе (бухгалтер, статистик, тысячи их). Поэтому порог входа должен быть низким, и (школа же, дети же) должен быть практически немедленный выхлоп, желательно наблюдаемый.
На мой личный взгляд, вариантов, собственно, три: VB.NET (да, бейсик), JavaScript и, да, он самый, несправедливо нелюбимый и оболганный Python. На первом можно за час-два собрать гуевую утилиту и за день написать виндовую игру класса "артиллерия", на втором можно нарисовать что-то динамичненькое в вебе за то же время; питон в этом плане менее гуев и чуть более задротский, но вот все-таки за него широчайший спектр применения, килотонны библиотек и вся прочая экосистема.
Циклы, условия и массивы есть, процедуры есть, ООП есть, хорошая работа со строками есть. Что еще надо, чтобы достойно встретить старость. На выходе мы имеем возможность объяснить, зачем вообще программировать, показать, что можно сделать дендрофекальным методом и кодом, заложить базовые концепты. Не факать мозги тем, кому это совсем не надо, но заложить какую-то базу для тех, кому это зачем-то потом понадобится, чтобы шурупы в мозг закручивались не по целине, а по старым следам. Кроме того, во втором и третьем (имхо и в первом, просто область специфическая, кто писал эксел-макросы, тот поймет) случае язык имеет некую ненулевую ценность и сам по себе.
Если говорить о втором языке - то это уже явно для тех, кто хочет связать жизнь с проклятыми ИТ, то есть программеров на ставку или полставки. А вот здесь уже нужно поднимать вопросы об эффективности, о-нотации, структурах данных, серьезном ООП, мультипоточности и что там еще - универский уровень, в общем-то. Более кровавый вариант - это С, менее кровавый - Go; альтернатива с бизнес-ориентацией - Java. Есть новомодный Rust, но я его не трогал вообще.
Теперь о плюсах. Я бы сказал, что плюсы - это идеальный третий язык. Я въезжал в него два раза, один около 2003, второй в 2019 - это заняло немало усилий и времени при том, что в первом случае это был мой пятый язык (Basic, Pascal, C, Java), а во втором - шестой (+ Python, и это не считая баша и повершелла). Плюсы офигенны, не спорю, но STL+Boost, на мой взгляд, доступны только для человека, который хорошо знает, зачем и почему ему это надо. Именно поэтому, на мой взгляд, плюсам нет места в общеобразовательной программе. Это магистратура или аспирантура - ну, по состоянию на 2020 год.
elglin: (Default)
Доподлинно знаю одну уважаемую контору, в которой плюсовики Питон иначе, как "петухоном" не называют. Ну он же тормозной, однопоточный и для дебилов - за то время, пока начинающий питонист уже начнет что-то говнокодить, тру начинающий плюсовик только начнет въезжать в RAII и STL. Но это лирика.
А тут вот начали опять в инете срать JSON за многословность и избыточность, и предлагать вместо него protobuf (в комментах справедливо помянули msgpack, который, как по мне, менее у**ищен, чем protobuf).
Да без фигни бинарный формат короче текстового, схематизированный короче несхематизированного, и оба быстрее парсятся. Но тут порылась собака в виде преждевременной оптимизации.
Да, мы все мним себя гуглами и амазонами (которым это при их сотнях кило-rps и мега-rps-ах актуально). Но пусть мы крепенькая такая контора с 36к заказов в день. Пусть это все прилетает за 10 часов - это... 1 rps. Ну пусть будет 10. Пусть у нас на каждый заказик (у нас же микросервисы, ема) летает сотня килобайтных JSON-ов. Пусть тысяча.
Итого у нас 10krps и 10 Мбайт/с (пусть 100 Мбит/с) внутреннего трафика. Прямо скажем, не тот трафик, чтобы оптимизировать. Да и затраты на разбор-сбор JSON-ов не займут большую часть процессорного времени.
А вот в чем мы круто выигрываем, так это в читабельности и дебаге. Да, схема занимает место, но вот она, родимая, перед глазами. И формат текстовый, то есть дамп трафика можно читать без hex-editor-а.
Какой-то умный человек написал, что в бизнес-программировании затраты на написание кода многократно превосходят затраты на его исполнение. Для интернет-гигантов и жесткого промышленного риалтайма это не так (и там как раз правят бал и плюсы, и няшна сишка), а вот в более частом случае конторы купи-продай это именно так, а потому питончик с джейсончиками вполне себе жив. И это я даже про похапе не сказал.
Не надо, короче, срать JSON. Очень хороший компромисс между машино- и человеко-читаемостью. Я бы сказал, офигенный дефолтный вариант для почти всего, если не получается обосновать, почему что-то другое лучше. И в львиной доле случаев его хватает.
elglin: (Default)
Я помню, что их три, и примерно два дня до собеса и два дня после помню, что какая значит. Помню, что суть в том, что все хранится один раз и именно там, где надо. Дальше у нас идут отношения 1-N, 1-1 и N-N, и как рубить второе с помощью вспомогательной таблицы (обычно поясняется на классическом примере авторов и книг).
Вся вот эта схематизация данных (равно как и строгая типизация в ЯП, но я отвлекаюсь) помогает, в том числе, заострить внимание на ценности данных. Что это самое важное во всей системе. Интернет, до кучи, изобилует историями о том, как пришедшую к успеху систему на какой-нибудь несхематизированной MongoDB потом приходится долго и нудно схематизировать, а то и переводить на какой-нибудь замшелый постгрес, потому что консистентность и производительность.
Но о чем, на самом деле, я. Вот у нас есть облако (AWS в данном случае). У него есть регионы. У нас есть приложения. А еще есть окружения вроде dev и prod. Между этими сущностями (регион, объект, приложение) отношение N-N везде, да еще и с необязательной принадлежностью. Еще аккаунт можно приплести, он тоже перцу добавляет.
В этой ситуации, когда нам надо собрать из всего этого рабочий конфиг, так и стоит действовать. Распиливаем все по сущностям, делаем наборы конфигов для аккаунта, окружения и там все такое, после чего это программно комбинируется аналогом SELECT * FROM a INNER JOIN b ON xxx INNER JOIN c ON yyy;
Да, сложно. Да, неинтуитивно. Но зато если ты давеча переименовал какую-то мелкую хрень, она у тебя переименовалась везде, где надо.

Но это, как выяснилось, не наш метод. Делаем иерархическую структуру папочек: регион-приложение-окружение. Ну ладно, общие настройки на регион наследуются, потому что терраформ умеет find_in_parents(). Ну а дальше у тебя столько полноценных конфигов приложения, в скольких регионах оно запилено. И еще хлеще с окружениями. Да, я понимаю, что те же коннстринги и все такое будут уникальны для каждого приложения... хотя темплейтинг вроде postgresql://{{app_user}}:{{app_password}}@{{env_psql}}:{{env_port}}/{{app_db}} это решает чаще, чем казалось бы.
Но нет. В итоге колоссальный объем самоповторений, репликация пусть коротенького, но одного и того же скрипта в 100500 экземплярах (что сразу делает его навечно неизменяемым, пусть он и написан через Ж).
Короче, я не могу понять, как до этой архитектуры доходили люди с сертификатами, катающиеся на re:Invent и занимающиеся Амазоном сильно дольше меня.

Возможно, они просто ни разу не работали с СУБД.
elglin: (Default)
Читнул тут питоновский скрипт одного из наших амерских питонистов, причем не самого худшего.
Я не буду тут про отсутствие def main(), стандартного if __name__ == '__main__' и посланный лесом PEP 8. Это крючкотворство.
Но зачем при импорте pathlib вызывать os.getcwd()? Это все равно, что в плюсовом коде вызывать malloc() - можно и работать будет, но так не принято.
Но это эскиз к вокалу. Напоминаю, у нас импортнуты pathlib и os (а, следственно, и os.path). То есть у нас есть перегруженный "/" для Path и os.path.join(). Но мы имеем (имена изменены):
foo = Path(__file__).parent # makes sense in context
# ...
bar= '{0}/xyzzy'.format(foo) # Sooo cross-platform
with open(bar, 'r') as f: # open() accepts path-like objects!
    # ... who cares ...

Естественно, foo продолжает оставаться типа pathlib.Path.
Вот как раз тот случай, когда код работает не благодаря, а вопреки программисту. Хотя этот же человек год назад писал assert x == True, так что надо радоваться прогрессу.
elglin: (Default)
Обнаружил для себя полезное свойство интереса к истории.
Вот у вас есть система ввода и обработки заказов, особенно если это реальный хайлоад, и она обмолачивает от сотен до сотни тысяч запросов в секунду, а каждый запрос обрабатывается за время от секунд до минут.
Представьте себе, как это бы выглядело в 19 веке. Что приходит вам из какой-то деревушки письмо: "прошу выслать мне керосиновую лампу и три бочки керосина". Вы пишете служебную записку на склад: "прошу зарезервировать для г-на У. лампу и три бочки керосина"; наутро вам приносят ответ: "Все найдено и зарезервировано" - и вы пишете уважаемому господину У., что у него есть неделя на то, чтобы оплатить два фунта, семь шиллингов и три пенса почтовым переводом. И так далее.
По сути, в этом нашем ойти происходит все то же самое, только намного большим потоком и быстрее. А так можно перемасштабировать задачу в ситуацию, которая легко осознается человеческим мозгом. А если учесть, что время было неспокойное, а люди бардачные, и все вот эти служебные записки и письма регулярно терялись или доходили с опозданием, то сразу сильно проще понимается, где нужно поретраить, где поставить таймаут и все такое.
Полезное это дело, короче. А если представить, что вместо вебхендлеров у вас сидят гремлины за конторским столиком, то получается практически Пратчетт.
elglin: (Default)
Своими руками закопал сегодня написанную мной же систему сборки серверов. Три года она верой и правдой работала, собрав, в том числе, и машины, на которых работает ее замена. Git blame не даст соврать, первый коммит 17 апреля 2017 года.
На ней я хорошо так научился башу и благодаря ей зашел в питон, на коем по сию пору пишу. Спасибо ей за это. Да и за многое другое, но об этом на заборе уже не пишут.
Впрочем, ее кикстарты без изменений переехали в новую систему, да и, что греха таить, новая выстроена наполовину на заделе старой, а еще на четверть - на фальстарте двухлетней давности по salt-cloud.
Так что код ее живет.
elglin: (Default)
В каждом языке, я думаю, есть свой brainfuck на эту тему. В Сях есть классическое a = b++; , которым пугают на первых занятиях, в питоне есть нюансы, что "если у тебя тупл из списков, то элементы списков можно менять".
Вчера напоролись на очередную идиосинкразию поша. Логика системы, не вдаваясь в подробности, требует взять файлик и кинуть его в ручку.
with open('file.txt') as fin:
    send_to_rest_handle(json.dumps({'data': fin.read()})) # The file is at most 20K

Ручка, естественно, валидирует ввод, и при десериализации очень хочет, чтобы data было str и никаких.
И тут казалось бы аналогичный код с винды начинает валить четырехсотки, причем именно валидацией.
Виндовый код был, казалось бы, настолько же прост:
Send-ToRestHandle -Data (@{"data" = (gc -raw 'file.txt')} | ConvertTo-Json)

И вот если вы наивно проверите тип того, что вам даст gc -raw, то это будет String!
> $foo = gc -raw file.txt
> $foo.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

А потом просто посмотрите, как этот якобы String сериализуется. Ни черта это не String, это пол-таблицы Менделеева. Правильный ответ: (gc -raw 'file.txt').value.

И в чем тут парадокс. Неплохой язык пошик, и я как-то писал, что если бы в линухе запилили python-shell, то он был бы не менее идиосинкразиен. Проблем здесь две:
1. "Интуитивно-неинтуитивное поведение".
2. За счет объектной модели, конвейера объектов и вот этого всего некоторые простые вещи делаются сложно. И вот на фоне баша, питона и даже Сей, где задача почитать-пофильтровать-пописать очень интуитивна, пошик именно в этом компоненте грустен.

Нытье

May. 14th, 2020 01:42 pm
elglin: (Default)
На работе сгорел к херам центральный свитч фабрики, уронив автомат PDU-шки. Не умерло почти ничего, что говорит о том, что, с одной стороны, мы все-таки не клинические болваны, но с другой - что хозяйство подзапущено. Умереть должно было ничего, но мы проморгали сдохший фибер-порт на одном сервере.
Грусть, печаль, ему шесть лет, сейчас постгарантийка ищет варианты на полную замену. Альтернатива - вынуть из теплого запаса десятилетний свитч, оставив некритичные сервера без второй ноги на сторадж. От хорошей жизни так не делают, но хорошая жизнь давно кончилась.
Бритье яка до бета-релиза подвигается с трудом, хотя после освоения pytest задача регрессионного тестирования упростилась. Проблема в том, что конкретно этот релиз перефигачивает полностью два куска логики, которые нельзя перефигачить покусочно. Ненавижу большие PR, но с альтернативами плохо.
Еще внезапно начали двигаться два проекта из долгого ящика, которые должны были лежать мертвым грузом до конца июня. С одной стороны, плюс, с другой стороны - и где под это найти человеко-часы?
И еще ремонт, будь он трижды неладен, который а) надо закончить до августа, чтобы спокойно уйти в поход б) надо еще понять масштабы бедствий, а то изначальная идея жены мне сразу напомнила тот анекдот про новую машину к новому лаку для ногтей в) надо бы еще деньги на него найти - не то, чтобы это прямо мегаквест, но бюджет ой не резиновый.
elglin: (Default)
Дернул меня черт вставить в фикстуру сборки тест-кейсов команду `len(test_array)`
198 получилось, это вообще нереально руками проверять. Писец ручному тестированию.
elglin: (Default)
The first year that you are using C++ STL, you wonder what kind of weed its designers smoked.
The rest of your life you wonder why designers of other libraries don't smoke the same weed.

GitHub

May. 4th, 2020 10:58 pm
elglin: (Default)
После кодинг-марафона длиной в день (рефакторинг и густая обмазка тестами просто так не даются) я решил, что я перестал быть днищем и стал говнокодером, а потому зарегался на сабже.
После того, как уточню на работе позицию юр.отдела по опенсорсу, выложу туда всякой фигни.
Ну или не выложу, хотя за это мы еще поборемся.
Page generated Jun. 15th, 2025 08:19 pm
Powered by Dreamwidth Studios