Обожаю эту дихтомию синхронного и асинхронного питона. Когда там завезли в питон asyncio? А я вам скажу, когда! async/await - это python 3.5. И это спокойный 2015 год😌То есть 10 лет назад вселенная питона расщепилась на "до" и "после". И вот "после" код в питоне заиграл новыми красками. Во всех смыслах, включая появление т.н. цветных функций.
Казалось бы, 10 лет это приличный срок, чтоб подтянуть всякие библиотеки и сделать возможным использование обоих подходов. Справедливости ради отмечу, что сделано было дохера. И в целом асинхронный питон - это уже давно продакшн реди решниее. Но все равно, то тут, то там вылезают приколы синхронного питона в асинхронном приложении 🐍
Вот и у меня щас немножк вылезло. Собственно пишу я сервис для сбора и экспорта продуктовых метрик в prometheus. Если посмотреть на список официальных SDK, то выяснится, что список ЯП ограничен следующими экземплярами: Go, Java, Python, Ruby, Rust. Поскольку я все таки хочу стать pro python developer'ом, мой выбор был предопределен.
Вот только когда я читал доку по SDK, я че то не заметил, что кастомный коллектор, который мне и нужен, - это синхронный генератор. А у меня асинхронное приложение 🤷
Ну как бы понятно, что это не супер большая проблема. У нас есть целых 3 варианта, как действовать:
* Сделать синхронный кэш метрик, который периодически обновляется асинхронно, а коллектор забирает данные синхронно
* Использовать ThreadPoolExecutor и вынести запросы в бд в отдельный тред прям в коллекторе
*Переписать все на Rust, чтоб было blazingly fast
На самом деле выглядит, как рабочий момент. Придется немношк поприседать. Ничего, бывает. Так что сегодня жопа не горит☺️
А к чему это я вообще говорю. Я на фоне этого всего вспомнил, что в php планируют завезти true async👍 Предвкушаю адский пердолинг на годы вперед, если примут 🤩
Казалось бы, 10 лет это приличный срок, чтоб подтянуть всякие библиотеки и сделать возможным использование обоих подходов. Справедливости ради отмечу, что сделано было дохера. И в целом асинхронный питон - это уже давно продакшн реди решниее. Но все равно, то тут, то там вылезают приколы синхронного питона в асинхронном приложении 🐍
Вот и у меня щас немножк вылезло. Собственно пишу я сервис для сбора и экспорта продуктовых метрик в prometheus. Если посмотреть на список официальных SDK, то выяснится, что список ЯП ограничен следующими экземплярами: Go, Java, Python, Ruby, Rust. Поскольку я все таки хочу стать pro python developer'ом, мой выбор был предопределен.
Вот только когда я читал доку по SDK, я че то не заметил, что кастомный коллектор, который мне и нужен, - это синхронный генератор. А у меня асинхронное приложение 🤷
Ну как бы понятно, что это не супер большая проблема. У нас есть целых 3 варианта, как действовать:
* Сделать синхронный кэш метрик, который периодически обновляется асинхронно, а коллектор забирает данные синхронно
* Использовать ThreadPoolExecutor и вынести запросы в бд в отдельный тред прям в коллекторе
*
На самом деле выглядит, как рабочий момент. Придется немношк поприседать. Ничего, бывает. Так что сегодня жопа не горит☺️
А к чему это я вообще говорю. Я на фоне этого всего вспомнил, что в php планируют завезти true async👍 Предвкушаю адский пердолинг на годы вперед, если примут 🤩
💯1
Ну штош. У нас тем временем очередная глобальная уязвимость в мире js под названием Shai-Hulud 2.0. Npm держит марку! красавцы! 👍
Подробности вы можете почитать в статье, но если вкратце, то
* Shai-Hulud это червь, который заражает npm пакеты
* Это делается посредством внедрения preinstall скрипта setup_bun.js
* Скрипт ворует все креденшиалы на локальной машине, включая npm креденшиалы, и публикует их в гихаб репозиториях
* Далее публикуется зараженая версия пакета в npm
* Поскольку в мире js все пакеты зависят от всех, это говнище быстренько распространяется на другие пакеты
Кароч пиздос! npm немношк пора поменять правила публикации новых версий. Как будто не стоит надеяться на то, что люди сами будут использовать 2FA.
Слава богу сегодня не обновлял пакеты😌
Подробности вы можете почитать в статье, но если вкратце, то
* Shai-Hulud это червь, который заражает npm пакеты
* Это делается посредством внедрения preinstall скрипта setup_bun.js
* Скрипт ворует все креденшиалы на локальной машине, включая npm креденшиалы, и публикует их в гихаб репозиториях
* Далее публикуется зараженая версия пакета в npm
* Поскольку в мире js все пакеты зависят от всех, это говнище быстренько распространяется на другие пакеты
Кароч пиздос! npm немношк пора поменять правила публикации новых версий. Как будто не стоит надеяться на то, что люди сами будут использовать 2FA.
Слава богу сегодня не обновлял пакеты😌
Datadoghq
The Shai-Hulud 2.0 npm worm: analysis, and what you need to know
Learn more about the Shai-Hulud 2.0 npm worm.
❤2👍1🙈1
Лол. Мне это напомнило недавние новости от майкрософт о том, что они наконец-то скоро пофиксят медленную загрузку проводника. Знаете как? Они будут в фоне предзагружать его🤡
🤡5🤮2
Возвращаясь к этому мему про схему веб айти. Не знаю как вам, а мне все слова на этой картинке знакомы. Кроме одного - left-pad. И я решил чекнуть, что это такое. Внезапно выяснилось, что за этим скрывается целая восхитительная история под названием npm left-pad incident. Го читать пересказ википедии ниже.
Для начала, что такое этот ваш left-pad. А это npm пакет. По сути, это одна функция из 11 строк, которая дополняет строку слева до нужной длины. Можно указать, каким символом дополнять. Например
Исходно создал этот мощный пакет разработчик по имени Azer Koçulu. Для простоты я буду звать его Андреем. Андрей был плодовитым опен сорс разработчиком из Калифорнии. Поговаривают, что он был мейнтейнером более 270+ пакетов в 2016 году. Одному из его пакетов не повезло получить имя kik.
Дело в том, что в то же самое время развивался и набирал популярность мессенджер с одноименным названием kik. Его разрабатывала компания, с названием состоящим из 3х букв. Угадайте название. Подсказака:буквы k i .
И вот ребята из этой компании решили использовать npm для создания своего собственного пакета под кодовым названием kik. Но попытка сделать это полностью провалилась, ибо Андрей уже застолбил имя. Что делают корпораты, когда какой-то человек мешает им делать бизнес? Правильно, они приходят к нему и говорят "проваливай, петушара"😡
Так и решили поступить адвокаты компании с Андреем. Сначала они написали ему письмо, в котором тупо попросили переименовать свой пакет во что-нибудь другое. Андрюша прихуел с такого поворота, но сказал, что он не будет ничо переименовывать. Тогда компания пошла на второй заход, и написала ему что-то вроде "Андрей, если ты нахуй щас же не переименуешь свой пакет, наши адвокаты постучатся сначала к тебе во входную, а потом и в заднюю дверь. Понял, ты, говно-жопа?" Андрей совсем не оценил такого мува, и резонно решил послать компанию на 3 буквы (не k i k).
После этого ребята из кика решили пойти к ребятам из других 3х букв n p m, и попросили передать имя kik им во владение. На удивление, две компании быстро пришли к согласию, и вот 18 марта 2016 года Андрей получил извещение о том, что имя kik таки у него забирают. 4 дня Андрей провел в полных ахуях. В конце концов окончательно психанув, просто удалил нахер все свои 270 пакетов из npm, и написал, что он рот топтал такой опен сурс. Среди этих пакетов был и left-pad.
Ой, что тут началось! После такой "шутки" Андрея лежаливсей маршруткой всем интернетом. Внезапно выяснилось, что пакет left-pad, который на гитхабе в то время имел всего 11 звезд, был прямой и непрямой зависимостью других пакетов. Например, пакета react 🤡 В тот день на 2.5 часа легли билды у таких небольших компаний как фейсбук, пейпал, нетфликс, спотифай.
Поскольку после удаления left-pad имя пакета освободилось, другой разработчик тут же создал клон оригинального пакета с тем же названием. Но версия у пакета по правилам npm должна была отличаться. Так шо это ничо не починило.
По итогу фиксинга npm высрали пост, где среди прочего написали npm won’t suddenly take your package name. Твердо и четко! В остальном же сослались на то, что лицензия пакета была MIT, так что код принадлежит всем. Поэтому пусть комьюнити делает форки и засталбливает названия оригинальный пакетов Андрея. Ну а они постараются сделать процесс анпаблишинга пакетов тяжелее, и обещают предотвратить публикацию зараженных пакетов🤡
Вот такая история. Знали о ней? За кого вы, за Андрея или за npm? должно ли имя пакета следовать принципу наименьшего удивления и принадлежать соответствующей компании пусть даже в ущерб нервным клеткам одного разработчика?
я просто в 2016м еще был нормальным парнем, и фронтендом особо не интересовался. Так что этот бриллиант прошел мимо меня.
Для начала, что такое этот ваш left-pad. А это npm пакет. По сути, это одна функция из 11 строк, которая дополняет строку слева до нужной длины. Можно указать, каким символом дополнять. Например
leftPad(12, 5, '0')
// => "00012"
Исходно создал этот мощный пакет разработчик по имени Azer Koçulu. Для простоты я буду звать его Андреем. Андрей был плодовитым опен сорс разработчиком из Калифорнии. Поговаривают, что он был мейнтейнером более 270+ пакетов в 2016 году. Одному из его пакетов не повезло получить имя kik.
Дело в том, что в то же самое время развивался и набирал популярность мессенджер с одноименным названием kik. Его разрабатывала компания, с названием состоящим из 3х букв. Угадайте название. Подсказака:
И вот ребята из этой компании решили использовать npm для создания своего собственного пакета под кодовым названием kik. Но попытка сделать это полностью провалилась, ибо Андрей уже застолбил имя. Что делают корпораты, когда какой-то человек мешает им делать бизнес? Правильно, они приходят к нему и говорят "проваливай, петушара"😡
Так и решили поступить адвокаты компании с Андреем. Сначала они написали ему письмо, в котором тупо попросили переименовать свой пакет во что-нибудь другое. Андрюша прихуел с такого поворота, но сказал, что он не будет ничо переименовывать. Тогда компания пошла на второй заход, и написала ему что-то вроде "Андрей, если ты нахуй щас же не переименуешь свой пакет, наши адвокаты постучатся сначала к тебе во входную, а потом и в заднюю дверь. Понял, ты, говно-жопа?" Андрей совсем не оценил такого мува, и резонно решил послать компанию на 3 буквы (не k i k).
После этого ребята из кика решили пойти к ребятам из других 3х букв n p m, и попросили передать имя kik им во владение. На удивление, две компании быстро пришли к согласию, и вот 18 марта 2016 года Андрей получил извещение о том, что имя kik таки у него забирают. 4 дня Андрей провел в полных ахуях. В конце концов окончательно психанув, просто удалил нахер все свои 270 пакетов из npm, и написал, что он рот топтал такой опен сурс. Среди этих пакетов был и left-pad.
Ой, что тут началось! После такой "шутки" Андрея лежали
Поскольку после удаления left-pad имя пакета освободилось, другой разработчик тут же создал клон оригинального пакета с тем же названием. Но версия у пакета по правилам npm должна была отличаться. Так шо это ничо не починило.
По итогу фиксинга npm высрали пост, где среди прочего написали npm won’t suddenly take your package name. Твердо и четко! В остальном же сослались на то, что лицензия пакета была MIT, так что код принадлежит всем. Поэтому пусть комьюнити делает форки и засталбливает названия оригинальный пакетов Андрея. Ну а они постараются сделать процесс анпаблишинга пакетов тяжелее, и обещают предотвратить публикацию зараженных пакетов🤡
Вот такая история. Знали о ней? За кого вы, за Андрея или за npm? должно ли имя пакета следовать принципу наименьшего удивления и принадлежать соответствующей компании пусть даже в ущерб нервным клеткам одного разработчика?
я просто в 2016м еще был нормальным парнем, и фронтендом особо не интересовался. Так что этот бриллиант прошел мимо меня.
🔥12❤1😁1😱1
Знаете, что общего между Егором Бугаенко и Артемием Лебедевым? И тот и другой много чего рассказывает. И у того, и у другого 50% это база, но другие 50% это откровенная дичарня.
Ладно, на самом деле я со всем уважением к Егору. У чувака опыта больше в 2 раза, его производительность видна на гитхабе, он пишет книги, читает лекции и его слушают. Так шо аргумент "сначала добейся" кажется мне уместным здесь. Но, думаю, я имею право не согласиться с ним в чем-то.
Около полугода назад попался мне ролик, где Егор отвечает на вопросы. И его там спросили, как он относится к DI - контейнерам. И он сослался на свою старую статью, и отметил, что его позиция с тех пор не изменилась. Штош, вот она эта статья под громким названием Dependency Injection Containers are Code Polluters. Она довольно старая. Но раз Егор по-прежнему ссылается на нее, то и мы скидок делать не будем. Давайте ознакомимся.
В статье Егор сначала приводит пример DI через конструктор, рассказывает на сколько это полезно по сравнению с инстанцированием зависимостей внутри класса. Ну допустим, тут мы верим, хотя Егор заканчивает объяснение фразой No need to discuss why. It’s obvious. Причем obvious - это ссылка stackexchange 😂 Так бы и написал "мне лень объяснять, давайте там сами, заебали".
"So far so good, but here comes the dark side—a dependency injection container" -- говорит нам Егор далее. Ну надеюсь щас нам расскажут про темную сторону.
После этого он вводит понятие DI-контейнера на примере старой библиотеки Google Guice, которая в данный момент не поддерживается. Удивительно, но оказывается, что если у тебя в приложении всего 2 класса, один из которых - это зависимость другого, то написать new A(new B()) окажется короче, чем конфигурировать контейнер! Вы знали об этом? Я ахуэл!
Кроме того, Егор отмечает, что существуют еще сценарии неправильного использования DI-контейнера такие как
* Field injection
* Setter injection
* Passing injector as dependency
* Making injector a global singlton (чем это плохо, кстати?)
И далее Егор заключает "If we put all of them aside, all we have left is the constructor injection explained above. And how does that help us? Why do we need it? Why can’t we use plain old new in the main class of the application? ... The container we created simply adds more lines to the code base, or even more files, if we use XML. And it doesn’t add anything, except an additional complexity."
Ну собственно все! Вот и вся аргументация! спасибо за внимание, нахуй!
Вот вам рецепт, как писать статьи: просто накидывайте обесценивающих вопросов и добивочка "про дополнительную сложность". Какие-то примеры, раскрытие тезисов, попытка разобраться в вопросах -- это для хабра 😂 в личном блоге можно просто надменно нести хуйню. Я, собственно, поэтому его и завел 🤫
Лан, на самом деле это еще не все. В конце Егор нам приводит пример Right way. Там гигантская портянка кода, которая не влезет никуда, поэтому ее кусок я ввиде скриншота приложил. Знаете, программирование - это в каком-то смысле квинтэссенция принципа "красота в глазах смотрящего". Егор смотрит на этот код и видит Right way, я смотрю на этот код и вижу клубень говна. Какие-то блять волшебные константы, ни одной повторяющейся зависимости. Где логер, Егор? В любом приложении он есть. Как ты его со своим right way собираешься вкорячивать?
О, я кстати придумал аргумент. "Егор, ну и чем твой код лучше XML? А?" Раунд!
Ладно, если по серьезке, то статья просто гавно! не потому что Егор там глобально неправ (хотя и это тоже), а потому что он свою позицию никак не раскрыл. Даже если бы он просто взял свой right way и переделал с использованием DI-контейнера, и вот там уже указал на additional complexity, и где конкретно она появляется -- в этом уже был бы толк и предмет для дискуссии. А так ну это просто наброс.
Хотел свое мнение написать про di-контейнеры, ноче то разбобмбился знатно, пока пост писал. Да и так про них много написано. Ну может потом. "мне лень объяснять, давайте там сами, заебали"
А вы как, согласны с Егором, что di-контейнеры - это зло?
Ладно, на самом деле я со всем уважением к Егору. У чувака опыта больше в 2 раза, его производительность видна на гитхабе, он пишет книги, читает лекции и его слушают. Так шо аргумент "сначала добейся" кажется мне уместным здесь. Но, думаю, я имею право не согласиться с ним в чем-то.
Около полугода назад попался мне ролик, где Егор отвечает на вопросы. И его там спросили, как он относится к DI - контейнерам. И он сослался на свою старую статью, и отметил, что его позиция с тех пор не изменилась. Штош, вот она эта статья под громким названием Dependency Injection Containers are Code Polluters. Она довольно старая. Но раз Егор по-прежнему ссылается на нее, то и мы скидок делать не будем. Давайте ознакомимся.
В статье Егор сначала приводит пример DI через конструктор, рассказывает на сколько это полезно по сравнению с инстанцированием зависимостей внутри класса. Ну допустим, тут мы верим, хотя Егор заканчивает объяснение фразой No need to discuss why. It’s obvious. Причем obvious - это ссылка stackexchange 😂 Так бы и написал "мне лень объяснять, давайте там сами, заебали".
"So far so good, but here comes the dark side—a dependency injection container" -- говорит нам Егор далее. Ну надеюсь щас нам расскажут про темную сторону.
После этого он вводит понятие DI-контейнера на примере старой библиотеки Google Guice, которая в данный момент не поддерживается. Удивительно, но оказывается, что если у тебя в приложении всего 2 класса, один из которых - это зависимость другого, то написать new A(new B()) окажется короче, чем конфигурировать контейнер! Вы знали об этом? Я ахуэл!
Кроме того, Егор отмечает, что существуют еще сценарии неправильного использования DI-контейнера такие как
* Field injection
* Setter injection
* Passing injector as dependency
* Making injector a global singlton (чем это плохо, кстати?)
И далее Егор заключает "If we put all of them aside, all we have left is the constructor injection explained above. And how does that help us? Why do we need it? Why can’t we use plain old new in the main class of the application? ... The container we created simply adds more lines to the code base, or even more files, if we use XML. And it doesn’t add anything, except an additional complexity."
Ну собственно все! Вот и вся аргументация! спасибо за внимание, нахуй!
Вот вам рецепт, как писать статьи: просто накидывайте обесценивающих вопросов и добивочка "про дополнительную сложность". Какие-то примеры, раскрытие тезисов, попытка разобраться в вопросах -- это для хабра 😂 в личном блоге можно просто надменно нести хуйню. Я, собственно, поэтому его и завел 🤫
Лан, на самом деле это еще не все. В конце Егор нам приводит пример Right way. Там гигантская портянка кода, которая не влезет никуда, поэтому ее кусок я ввиде скриншота приложил. Знаете, программирование - это в каком-то смысле квинтэссенция принципа "красота в глазах смотрящего". Егор смотрит на этот код и видит Right way, я смотрю на этот код и вижу клубень говна. Какие-то блять волшебные константы, ни одной повторяющейся зависимости. Где логер, Егор? В любом приложении он есть. Как ты его со своим right way собираешься вкорячивать?
О, я кстати придумал аргумент. "Егор, ну и чем твой код лучше XML? А?" Раунд!
Ладно, если по серьезке, то статья просто гавно! не потому что Егор там глобально неправ (хотя и это тоже), а потому что он свою позицию никак не раскрыл. Даже если бы он просто взял свой right way и переделал с использованием DI-контейнера, и вот там уже указал на additional complexity, и где конкретно она появляется -- в этом уже был бы толк и предмет для дискуссии. А так ну это просто наброс.
Хотел свое мнение написать про di-контейнеры, но
А вы как, согласны с Егором, что di-контейнеры - это зло?
👍8❤1🤗1
Решил вчера вернуться на десктопный линукс после 5 лет перерыва. Поставил кубунту. Перезагрузился 2 раза - все ок. На 3й раз увидел вот это.
Годы идут, а к десктопному линуксу как нельзя было без вазилина прикасаться лет 10 назад, так и до сих пор нельзя. Оплот стабильности😊 зато будет, чем заняться в это воскресенье.
PS. Да, я подозреваю, что это какая-то проблема с grub, secure boot и тем, что это вторая система. Но все равно прикольно, что на ровном месте приключения. Винда кстати норм грузится🤷
Годы идут, а к десктопному линуксу как нельзя было без вазилина прикасаться лет 10 назад, так и до сих пор нельзя. Оплот стабильности😊 зато будет, чем заняться в это воскресенье.
PS. Да, я подозреваю, что это какая-то проблема с grub, secure boot и тем, что это вторая система. Но все равно прикольно, что на ровном месте приключения. Винда кстати норм грузится🤷
👍3❤2
Карочи, опять про питоновский линтер pylint. Не буду повторять (хотя повторю), что в наше время, если линтер не умеет сам ошибки исправлять, то это немношк кринге. Ну да ладно😔
Седня хотел поговорить про конкретное правило линтера, а именно про порядок импортов. У нас есть стандарт PEP8, который декларирует следующие группы импортов:
1. Импорты стандартной библиотеки
2. Импорты сторонних либ
3. Локальные импорты
Группы импортов должны размещаться в начале каждого файла именно в таком порядке. Они должны быть разделены пустой строкой. Код должен идти после. И pylint по дефолту требует выполнения этого условия. Вроде норм, но!Импорты не реордятся автоматически 😡
Есть такая функция из модуля dotenv, называется load_dotenv(). Любой сеньор догадается, что эта функция занимается тем, что загружает переменные окружения. Поэтому, мы ее где нить в начале скрипта вызываем, и дальше у нас все окружение доступно.
Поскольку я пареньпидаристичный педантичный, я хочу, шоб мое приложение даже не запускалось, если какие-то переменные окружения отсутвуют, и сразу падало с ошибкой. Для этого в начале своего модуля, который, например, отвечает за интеграцию с каким-то сервисом я воткну что-то вроде
Вроде нойм. Но вопрос, а куда воткнуть load_dotenv()? Вы можете подумать, что load_dotenv надо воткнуть сразу после импортов в рутовом файле приложения. Ну типа, это начало "как бы" кода. Но в таком случае, мы сразу получаем ошибку, потому что наш import service окажется до load_dotenv() и переменные не будут загружены на момент выполнения импорта. Ведь питон просто исполняет код внутри файлов по мере поступления импортов.
И тут получается 2 стула:
* Либо мы вызываем load_dotenv() в каждом таком файле с env переменными после импортов, и pylint счастлив
* Либо мы втыкаем его между импортами прямо перед группой локальных импортов в рутовом файле
Во втором случае у pylint сгорает срака. Потушить ее можно поместив все локальные импорты между дtрективами
Я че то думал-думал, и решил, что load_dotenv() в каждом файле это какая-то параша. Хоть вызов load_dotenv() несколько раз на корректность не влияет, вроде как оно замедляет старт скрипта. Но я не бенчмаркал🤷 Поэтому выбрал второй варик.
И тут многие проженные питонисты скажут "Ррряяя, ты туповатый. Надо делать отдельный класс-хранилище переменных, который ты будешь инициализировать на старте. У тебя опять skill issues!". Не кипятитись мои горячие питонячие пирожочки. Тут важно еще раз обратиться к цели: скрипт не должен даже стартануть, если какой-то конфиг пропущен. Я не должен узнать об этом в рантайме. И все должно быть типизированно. Никакое класс-хранилище эту проблему не решит.
Или я неправ? Делитесь в комментах, как у вас дела обстоят с енв переменными. Или напихайте мне за высосанную из пальца проблему! 😘
Седня хотел поговорить про конкретное правило линтера, а именно про порядок импортов. У нас есть стандарт PEP8, который декларирует следующие группы импортов:
1. Импорты стандартной библиотеки
2. Импорты сторонних либ
3. Локальные импорты
Группы импортов должны размещаться в начале каждого файла именно в таком порядке. Они должны быть разделены пустой строкой. Код должен идти после. И pylint по дефолту требует выполнения этого условия. Вроде норм, но!
Есть такая функция из модуля dotenv, называется load_dotenv(). Любой сеньор догадается, что эта функция занимается тем, что загружает переменные окружения. Поэтому, мы ее где нить в начале скрипта вызываем, и дальше у нас все окружение доступно.
Поскольку я парень
SERVICE_HOST: Final[str | None] = os.getenv("SERVICE_HOST")
if SERVICE_HOST is None:
raise RuntimeError("SERVICE_PORT is not set далбаеб")
Вроде нойм. Но вопрос, а куда воткнуть load_dotenv()? Вы можете подумать, что load_dotenv надо воткнуть сразу после импортов в рутовом файле приложения. Ну типа, это начало "как бы" кода. Но в таком случае, мы сразу получаем ошибку, потому что наш import service окажется до load_dotenv() и переменные не будут загружены на момент выполнения импорта. Ведь питон просто исполняет код внутри файлов по мере поступления импортов.
И тут получается 2 стула:
* Либо мы вызываем load_dotenv() в каждом таком файле с env переменными после импортов, и pylint счастлив
* Либо мы втыкаем его между импортами прямо перед группой локальных импортов в рутовом файле
Во втором случае у pylint сгорает срака. Потушить ее можно поместив все локальные импорты между дtрективами
# pylint: disable=wrong-import-position и # pylint: enable=wrong-import-position (см. скриншот кода из прода 😱).Я че то думал-думал, и решил, что load_dotenv() в каждом файле это какая-то параша. Хоть вызов load_dotenv() несколько раз на корректность не влияет, вроде как оно замедляет старт скрипта. Но я не бенчмаркал🤷 Поэтому выбрал второй варик.
И тут многие проженные питонисты скажут "Ррряяя, ты туповатый. Надо делать отдельный класс-хранилище переменных, который ты будешь инициализировать на старте. У тебя опять skill issues!". Не кипятитись мои горячие питонячие пирожочки. Тут важно еще раз обратиться к цели: скрипт не должен даже стартануть, если какой-то конфиг пропущен. Я не должен узнать об этом в рантайме. И все должно быть типизированно. Никакое класс-хранилище эту проблему не решит.
Или я неправ? Делитесь в комментах, как у вас дела обстоят с енв переменными. Или напихайте мне за высосанную из пальца проблему! 😘
❤4
Блин, такая вообще обида у меня щас конечно😢 аж до слез!
На прошлой неделе тюнил потребление памяти в нашем монололитном макросервисе на symfony. Че то оно было подозрительно высокое. И обнаружил, что в какой-то момент бэкграунд джоба загружает из базы массив на 200 000 интов. Чтобы подсчитать их количество🤡 Ну это ладно. Думаю, все так делают.
Чтоб достать это все из базы, используется доктриновский getSingleColumnResult(), который возвращает лист со значениями одного столбца. И в этот момент потребление памяти подскакивает до 60 мб, шо как бы нихуясебе. Ну и вы можете сказать "а че ты хотел. 200 000 интов в массиве на пхп, это тебе не шутки!"
А давайте все таки прикинемписю к носу потребление памяти для такого списка. Любой скаляр в пхп занимает 16 байт, потому что именно столько занимает zval. И тут, как математик, я вам могу сказать что, (16 х 200 000) / 1024 / 1024 = 3мб. И с этим уже можно жить. И если, как физик, я создам такой лист с нуля, то примерно такое потребление памяти я и увижу. Но откуда 60 мб? Стало быть, какое-то непотребство происходит внутри доктрины.
Стал разбираться и быстро выяснил, что под капотом у getSingleColumnResult() используется PDOStatement::fetchAll c флагом PDO::FETCH_NUM. Этот флаг возвращает результат в виде списка списков с одним элементом. Таким образом, доктрина была поймана за руку, как дешевка! Ведь у каждого массива в пхп есть оверхед в пару сотен байт. Вот оно и вылазиет.
Тут же созрел хитрый план, что на выхах я буду врываться в опен сурс со своим классным пулл реквестом, где заменю флаг на PDO::FETCH_COLUMN. И меня тут же все полюбят, и я стану красавчиком, наконец😌
Начал еще раз все перепроверять на новой версии доктрины, а оно сука работает как надо! Оказывается, на прошлой неделе они выпустили фикс, где эта проблема была закрыта😔 а соответствующему пру уже 5 месяцев.
Вот так провалилась очередная попытка стать классным😢
Выводы:
* Жизнь - жестокая штука
* Своевременность - это очень важно
* За любым массивом кроется память
Спасибо, что выслушали ❤️
На прошлой неделе тюнил потребление памяти в нашем монололитном макросервисе на symfony. Че то оно было подозрительно высокое. И обнаружил, что в какой-то момент бэкграунд джоба загружает из базы массив на 200 000 интов. Чтобы подсчитать их количество🤡 Ну это ладно. Думаю, все так делают.
Чтоб достать это все из базы, используется доктриновский getSingleColumnResult(), который возвращает лист со значениями одного столбца. И в этот момент потребление памяти подскакивает до 60 мб, шо как бы нихуясебе. Ну и вы можете сказать "а че ты хотел. 200 000 интов в массиве на пхп, это тебе не шутки!"
А давайте все таки прикинем
Стал разбираться и быстро выяснил, что под капотом у getSingleColumnResult() используется PDOStatement::fetchAll c флагом PDO::FETCH_NUM. Этот флаг возвращает результат в виде списка списков с одним элементом. Таким образом, доктрина была поймана за руку, как дешевка! Ведь у каждого массива в пхп есть оверхед в пару сотен байт. Вот оно и вылазиет.
Тут же созрел хитрый план, что на выхах я буду врываться в опен сурс со своим классным пулл реквестом, где заменю флаг на PDO::FETCH_COLUMN. И меня тут же все полюбят, и я стану красавчиком, наконец😌
Начал еще раз все перепроверять на новой версии доктрины, а оно сука работает как надо! Оказывается, на прошлой неделе они выпустили фикс, где эта проблема была закрыта😔 а соответствующему пру уже 5 месяцев.
Вот так провалилась очередная попытка стать классным😢
Выводы:
* Жизнь - жестокая штука
* Своевременность - это очень важно
* За любым массивом кроется память
Спасибо, что выслушали ❤️
👏12😁6❤4👍3
Ну что, мои дорогие бомбята! Вот и наступил 2026. Я не очень люблю итоги года, поэтому всех просто поздравляю. Надеюсь все выжили и готовы активничать дальше. Может не прям сегодня конечно😊
Думаю 2026 год даст не меньше поводов побомбить, чем 2025. А это значит, будет о чем написать, и что обсудить. Я, в свою очередь, обещаю, что контент, как и прежде, останется человеко-генерированным, но не всегда полезным) Но я щитаю, что польза - это про другие каналы. Здесь я скорее про фан и эмоции вокруг нашего любимого программирования. Ну и всегда рад показать, что обосраться - это не зазорно, а иногда и очень здорово 😀
Всех с новым годом! 🥳 Хорошо отдохните, шоб сделать врыв в следующий год максимально мощным!
P.S. Праздничный кот Кристофер передает всем привет
Думаю 2026 год даст не меньше поводов побомбить, чем 2025. А это значит, будет о чем написать, и что обсудить. Я, в свою очередь, обещаю, что контент, как и прежде, останется человеко-генерированным, но не всегда полезным) Но я щитаю, что польза - это про другие каналы. Здесь я скорее про фан и эмоции вокруг нашего любимого программирования. Ну и всегда рад показать, что обосраться - это не зазорно, а иногда и очень здорово 😀
Всех с новым годом! 🥳 Хорошо отдохните, шоб сделать врыв в следующий год максимально мощным!
P.S. Праздничный кот Кристофер передает всем привет
❤14🎉10💯1
Уууу сукаа. Выбесился с двух вещей вчера.😡
1. Claude Sonnet 4.5 (потому что пиздабол)
2. github (потому что майкрософт нихера там не улучшает и всем поебать на запросы пользователей)
В чем суть. Пытался задеплоить пет проект. Шоб вы понимали, это просто старый добрый static веб сайт из трех файликов: html, js, css. Никаких фреймворков, баз данных и прочего бэкендского говнишка. Всякие либы гружу с CDN. Полный минимализм. Боже, как я по этому скучаю на работе😔
А в другом репозитории у меня находится то, что представляет определеннуюценность прелессть, точнее ее исходники. И статичный сайт просто дает удобный доступ к этой прелести.
И я спрашиваю у клода "а могу я в github actions просто собрать свою прелессть во время публикации релиза и просто запихать ее как ассет, а потом на своем сайте просто грузить этот ассет по прямой ссылке?"
И клод мне отвечает: "Отличная идея! Ты такой умный и красивый! Кстати, github releases поддерживает CORS, так что проблем не будет!" Я его про CORS даже не спрашивал, но он вообще красавчик, и сам мне написал про это👍
Для тех кто не в курсе, что такое CORS (Cross-Origin Resource Sharing). Это такая штука, которая позволяет бровзеру загружать ресурсы с другого домена. В данном случае, мне нужно грузить ассеты с гитхаба, и это другой домен. Поэтому поддержка CORS с их стороны будет как нельзя кстати.
Проблема в том, что у гитхаба нет поддержки CORS для ассетов релизов 🤡 Зато есть тикет, которому 3 года, с просьбой добавить эту самую поддержку. И я узнаю об этом в тот момент, когда уже все нахуячил и пытаюсь задеплоить. Всякие штуки вроде raw.githubusercontent.com позволяют загружать только контент репозиториев, но не ассеты релизов.
У этой проблемы существует 2 решения:
* Использовать прокси
* Добавить стадию билда, где перед публикацией загружать ассет и класть его рядом с другими файлами
Я выбрал второй варик, потому что первый - это какое-то нереальное дрочево, если делать свой прокси, и суперненадежно, если использовать публичные. Благо, что мой хостинг провайдер netlify позволяет изи сделать билд😍 Вообще про netlify можно отдельно написать, потому что прям очень понравилось. Если вам надо захостить простой сайт БЕСПЛАТНО, то netlify - это прям мой рекомендасьон!
Выводы:
1. github не поддерживает CORS. Говорят, даже их api не поддерживает CORS, хотя в доке написано обратное, но тут я не проверял 🤷
2. llm врали, врут и будут врать. Причем делают они это так убедительно, что каким бы подозревакой ты не был, разок-другой тебя все равно наебунькают. К сожалению или счастью, общая производительность благодаря им все равно гораздо выше. Поэтому придется принять эту реальность. Кожанный мешок может лишь научиться вычленять критичные факты, и вовремя их проверять (используя те же llm для скорости проверки), прежде чем начинать реализовывать предложенный план.
Пока что с пунктом 2 у меня проблемы. Нейронки нахлабучивают меня регулярно, а я им даже в чан не могу прописать 😢
1. Claude Sonnet 4.5 (потому что пиздабол)
2. github (потому что майкрософт нихера там не улучшает и всем поебать на запросы пользователей)
В чем суть. Пытался задеплоить пет проект. Шоб вы понимали, это просто старый добрый static веб сайт из трех файликов: html, js, css. Никаких фреймворков, баз данных и прочего бэкендского говнишка. Всякие либы гружу с CDN. Полный минимализм. Боже, как я по этому скучаю на работе😔
А в другом репозитории у меня находится то, что представляет определенную
И я спрашиваю у клода "а могу я в github actions просто собрать свою прелессть во время публикации релиза и просто запихать ее как ассет, а потом на своем сайте просто грузить этот ассет по прямой ссылке?"
И клод мне отвечает: "Отличная идея! Ты такой умный
Для тех кто не в курсе, что такое CORS (Cross-Origin Resource Sharing). Это такая штука, которая позволяет бровзеру загружать ресурсы с другого домена. В данном случае, мне нужно грузить ассеты с гитхаба, и это другой домен. Поэтому поддержка CORS с их стороны будет как нельзя кстати.
Проблема в том, что у гитхаба нет поддержки CORS для ассетов релизов 🤡 Зато есть тикет, которому 3 года, с просьбой добавить эту самую поддержку. И я узнаю об этом в тот момент, когда уже все нахуячил и пытаюсь задеплоить. Всякие штуки вроде raw.githubusercontent.com позволяют загружать только контент репозиториев, но не ассеты релизов.
У этой проблемы существует 2 решения:
* Использовать прокси
* Добавить стадию билда, где перед публикацией загружать ассет и класть его рядом с другими файлами
Я выбрал второй варик, потому что первый - это какое-то нереальное дрочево, если делать свой прокси, и суперненадежно, если использовать публичные. Благо, что мой хостинг провайдер netlify позволяет изи сделать билд😍 Вообще про netlify можно отдельно написать, потому что прям очень понравилось. Если вам надо захостить простой сайт БЕСПЛАТНО, то netlify - это прям мой рекомендасьон!
Выводы:
1. github не поддерживает CORS. Говорят, даже их api не поддерживает CORS, хотя в доке написано обратное, но тут я не проверял 🤷
2. llm врали, врут и будут врать. Причем делают они это так убедительно, что каким бы подозревакой ты не был, разок-другой тебя все равно наебунькают. К сожалению или счастью, общая производительность благодаря им все равно гораздо выше. Поэтому придется принять эту реальность. Кожанный мешок может лишь научиться вычленять критичные факты, и вовремя их проверять (используя те же llm для скорости проверки), прежде чем начинать реализовывать предложенный план.
Пока что с пунктом 2 у меня проблемы. Нейронки нахлабучивают меня регулярно, а я им даже в чан не могу прописать 😢
GitHub
Download release assets and zipball with CORS · community · Discussion #45446
Select Topic Area Bug Body Right now, unlike raw.githubusercontent.com, codeload.github.com (for downloading zipballs) and the release assets download bucket do not support CORS. I need this functi...
😢5👍2👏2❤1
Те, кто ковыряются с пыхой знают, насколько важен стат анализ в их коде. В наши дни наличие phpstan или psalm в дев пайплайне уже вариант нормы. Ну это, если вы не wordpress разработчик — вам, ребята, мои искренние соболезнования и обнимашки🙆♂️
Тем не менее, существует огромное количество легаси проектов, в которых вместо современных DTO с readonly классами, все еще повсеместно используются наши любимые array. Но даже в современных проектах, внешний json незамедлительно декодится во что? Правильно, в std объект или массив! В этих ситуациях разработчик может почувствовать недостаток типизации
При этом, и phpstan, и psalm поддерживают array и object shapes в аннотациях типов, что позволяет добавить типизацию для массивов и объектов. Но аннотировать такое ручками часто больно и лениво😔
Поэтому мне пришла в голову идея "а что если бы можно было сделать дамп переменной, закинуть ее куда-то и на выходе получить аннотации типов?" Я не очень хорош в гуглеже, но ничего готового или похожего найти не получилось. Ну и будем честными, это отличная задачка на тему "напиши парсер с нуля", которую стоит попробовать сделать любому разработчику. Правда в моем случае, писал парсер я руками клода, хых.
Короче, в итоге родилась cli утилита hell2shape (https://github.com/Feolius/hell2shape)🤩
Но! я прекрасно понимаю вас, мои ленивые пирожочки, что вы даже исполняемый файл заленитесь скачать, и уж тем более не будете ставить это через композер. Поэтому специально для вас я сделал веб версию, чтоб вам вообще можно было не напрягаться https://hell2shape.netlify.app/, а сразу попробовать! Из прекрасного здесь то, что это все работает локально в браузере через php-wasm😍 Как следствие, я не парюсь насчет сервера, а вы не паритесь насчет ваших данных!
Теперь немного оправдашек:
1. Сразу скажу, что я не ставил задачу сгенерировать все типы абсолютно правильно. Это и невозможно! Тут скорее смысл в том, чтоб у разработчика появился некий бейзлайн, который он скопировал в ide, а дальше уже допиливал сам.
2. Генератор тупой как пробка. Это означает, что если вы ему дали на вход лист, в котором каждый элемент уникальный — на выходе вы получите лист, у которого элемент это юнион из кучи типов. Никакого лимита на количество типов в юнионе пока что нет.
3. Ну и в целом тема то сложная, обосраться можно много где. Так что не судите строго. Просто шлите баг репорты 😊
Пожалуйста пробуйте. И пишите, че думаете. Говно, не говно? На сколько полезно вам будет?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥6🤝5
Вы не просили, но я все равно принес вам обзор на книгу. В этот раз отзыв будет о труде под названием "Распределенные данные" за авторством Алекса Петрова☝️Про себя я ее называю "недокабанчик".
Мы с Маськой изучили книгу и ставим ей четкие 5.5 из 10. Маська попросила накинуть 0.5 за рыбу на обложке😊Данную оценку можно интерпретировать как "Книга не полное говно, но и настоятельно рекомендовать ее не буду".
Это книга о базах данных в разрезе подсистем хранения. И название здесь совершенно сбивает с толку. Можно подумать, что она про базы данных исключительно в распределенных системах. Но это не так. Книга состоит из двух частей, и первая из них (бОльшая) посвящена исключительно одноузловым системам. И только вторая часть про алгоритмы распределенных СУБД.
В этой книге рассматриваются следующие темы:
* B-деревья
* Очень много разных B-деревьев
* Больше-больше B-деревьев
* LSM - деревья
* Важные слова про распределенные системы, куча бессмысленных описаний алгоритмов распределенных транзакций и выбора лидера, CAP - теорема.
Впринципи, больше ничего нет. Да, в книге про распределенные данные не написано толком ничего про репликацию и шардирование. Так бывает.
Тут есть две большие проблемы, которые и делают книгу "недокабанчиком". Первая заключается в том, что вы с книгой находитесь в противофазе. Это означает, что книга берет какой-то относительно простой факт, и начинает его разжевывать с помощью полотна текста и кучи рисунков. И ты такой думаешь "да заебал ты, давай дальше". Но зато, если какой-то хардкорный алгоритм рассматривается, то там автор уж как следует поскупится на объяснения. И ты перечитываешь это все раз за разом, а понимания не приходит😪
Второй момент связан с тем, что как учебник она так себе. Это легко можно понять по тому, что в книге очень много ссылок на БУДУЩИЕ главы. Я считаю, такое допустимо, только когда книга - справочник. Кстати, вы можете легко это исправить, если будете читать книгу задом наперед🤡
Но не только в организации дело. Пока читаешь книгу, то создается впечатление, что автор не поработал над материалом. Он просто брал научные статьи и пересказывал их общими словами, в надежде, что так оно лучше поймется. Не поймется. Оно как зашло, так и вылетело тут же.
Еще хуже обстоит дело, если есть возможность сравнить материал с кабанчиком. Например, можно взять LSM-деревья. Кабанчик шикарен. Он начинает от простой идеи хранения упорядоченных списков и постепенно расширяет ее, при этом избегая лишних сложностей. Тут же тебе сначала предстоит прочитать 5 страниц какой-то пежни ни о чем, а потом начинается жестб. Мне кажется, я бы нихера не понял без кабанчика.
В паре мест автор вообще прикололся. Нахуя-то вставил в книгу описание жестких вещей, над которыми ты прям пыжишься, чтоб понять. А в конце добавляет "мне неизвестны примеры практического использования этого алгоритма"🤡
Книга будет полезна, если вы хотите разобраться в
* B-деревьях (круто описаны)
* общих вещах и проблемах, связанных с распределенными системами
Она неплохо дополняет кабанчика в каких-то темах. Например, термин "линеаризуемость" может быть лучше понят с помощью этой книги. Но все равно пользы мало.
Вердикт: могло бы быть и лучше!
Кто найдет ошибку на второй фотке?
Мы с Маськой изучили книгу и ставим ей четкие 5.5 из 10. Маська попросила накинуть 0.5 за рыбу на обложке😊Данную оценку можно интерпретировать как "Книга не полное говно, но и настоятельно рекомендовать ее не буду".
Это книга о базах данных в разрезе подсистем хранения. И название здесь совершенно сбивает с толку. Можно подумать, что она про базы данных исключительно в распределенных системах. Но это не так. Книга состоит из двух частей, и первая из них (бОльшая) посвящена исключительно одноузловым системам. И только вторая часть про алгоритмы распределенных СУБД.
В этой книге рассматриваются следующие темы:
* B-деревья
* Очень много разных B-деревьев
* Больше-больше B-деревьев
* LSM - деревья
* Важные слова про распределенные системы, куча бессмысленных описаний алгоритмов распределенных транзакций и выбора лидера, CAP - теорема.
Впринципи, больше ничего нет. Да, в книге про распределенные данные не написано толком ничего про репликацию и шардирование. Так бывает.
Тут есть две большие проблемы, которые и делают книгу "недокабанчиком". Первая заключается в том, что вы с книгой находитесь в противофазе. Это означает, что книга берет какой-то относительно простой факт, и начинает его разжевывать с помощью полотна текста и кучи рисунков. И ты такой думаешь "да заебал ты, давай дальше". Но зато, если какой-то хардкорный алгоритм рассматривается, то там автор уж как следует поскупится на объяснения. И ты перечитываешь это все раз за разом, а понимания не приходит😪
Второй момент связан с тем, что как учебник она так себе. Это легко можно понять по тому, что в книге очень много ссылок на БУДУЩИЕ главы. Я считаю, такое допустимо, только когда книга - справочник. Кстати, вы можете легко это исправить, если будете читать книгу задом наперед🤡
Но не только в организации дело. Пока читаешь книгу, то создается впечатление, что автор не поработал над материалом. Он просто брал научные статьи и пересказывал их общими словами, в надежде, что так оно лучше поймется. Не поймется. Оно как зашло, так и вылетело тут же.
Еще хуже обстоит дело, если есть возможность сравнить материал с кабанчиком. Например, можно взять LSM-деревья. Кабанчик шикарен. Он начинает от простой идеи хранения упорядоченных списков и постепенно расширяет ее, при этом избегая лишних сложностей. Тут же тебе сначала предстоит прочитать 5 страниц какой-то пежни ни о чем, а потом начинается жестб. Мне кажется, я бы нихера не понял без кабанчика.
В паре мест автор вообще прикололся. Нахуя-то вставил в книгу описание жестких вещей, над которыми ты прям пыжишься, чтоб понять. А в конце добавляет "мне неизвестны примеры практического использования этого алгоритма"🤡
Книга будет полезна, если вы хотите разобраться в
* B-деревьях (круто описаны)
* общих вещах и проблемах, связанных с распределенными системами
Она неплохо дополняет кабанчика в каких-то темах. Например, термин "линеаризуемость" может быть лучше понят с помощью этой книги. Но все равно пользы мало.
Вердикт: могло бы быть и лучше!
Кто найдет ошибку на второй фотке?
👏7❤🔥4🔥2