Портрет 4X_Pro
Был в Сети 21 дек. 2024 г., 14:10
Мультиблог
4X_Pro
Кратко о себе: Web-разработчик. Пишу на PHP, Python, JavaScript. Знаю Ruby и Go, со студенческих времён более-менее помню C и asm. Специализируюсь на ускорении загрузки сайтов и разработке ботов для Telegram. Linuxоид (использую Debian+LXDE). Сторонник IndieWeb, slow lifer.

Социальные сети


Новости сайта в Telegram

t.me/4x_pro

Лог жизни

Лог моей жизни, где я фиксирую наиболее эмоционально значимые для меня события и текущее настроение. Является продолжением блога, который я вел в ЖЖ с ноября 2004 по апрель 2018 года.


Проект, который никак не удаётся столкнуть

4X_Pro
Опять накатывало «уплотнение жизни», из-за которого долго не писал в блог. Всё началось с того, что взялся за очередную freelance-задачу — оптимизиацию скорости загрузки сайта. Сначала долго не мог заставить себя начать. Потом, когда всё же приступил, обнаружил, что всё плохо — на сервере стоит CentOS с древним-древним Apache, не поддерживающим HTTP/2. Нашёл возможность поставить более новую версию обходными путями, но оказалось, что для поддержки HTTP/2 нужно переключаться из preforked mode в какой-то другой. Почему-то я думал, что там PHP работает в режиме Apache module, который только в preforked и доступен, и не стал этого делать. Вместо этого решил было поставить nginx. Потом вспомнил, что у клиентов установлен ISPmanager, и если я поставлю nginx, то возможность управления сайтами через него может перестать работать.
В этот момент я совсем было расстроился, но потом пришло в голову, что видел, что через ISPManager можно управлять и сайтами на nginx, а значит, где-то в настройках должна быть возможность переключения. После недолгого поиска возможность нашлась. Причём оказалось, что ISPManager может и сам nginx поставить, и автоматически конфиги сконвертировать. Затем решил переключить версию PHP с 5.4 на 7.1, чтобы уменьшить время генерации страницы. Сайт просто вырубился без каких-либо сообщений об ошибках. Покопавшись, я обнаружил, что проблема в том, что в скрипте магазина используется работа через расширение mysql вместо mysqli. Хорошо, что я с этим уже сталкивался, и было готовое решение. Дальше осталось только настроить сжатие, кеширование, включить HTTP/2 и радоваться тому, как резко подросли показатели скорости сайта. Потом для полного счастья включил еще TLS 1.3.
Но увы, радость была недолгой. Оказалось, что горе-оптимизаторы, которые занимались сайтом до меня, применили жульнический приём: отключали часть скриптов, если User-agent содержит Lighthouse. Когда я это убрал, оценка упала чуть ли не до того же уровня, который был изначально. Было жутко обидно. Потом, правда, удалось решить часть проблем минификацией некоторых скриптов и асинхронной загрузкой вспомогательных CSS.
Потом ещё немного повозился с уменьшением CLS (то, насколько «ездит» изображение по экрану при загрузке), переводом картинок в WebP, прописыванием всяких alt, height, width, другими мелкими оптимизациями, и считал, что дело сделано. Вдобавок ещё переписал несколько SQL-запросов, ускорив их почти в два раза, чтобы уменьшить время выдачи HTML-страницы.
В итоге добился показателей порядка 90 даже для мобильной версии, и уже было считал задачу выполненной. Но решил проверить и другие страницы сайта. И там всё оказалось гораздо хуже, чем я ожидал: там показатель производительности просел примерно до 50. Отчасти из-за того, что опять же предыдущие оптимизаторы для главной сделали отдельный CSS без лишних правил, а на остальных грузился здоровенный общий, отчасти — из-за того, что в картинках товаров использовался формат JPEG с неоптимальным сжатием. Пришлось переводить картинки на WebP. На первый взгляд, задача простая, но проблема вылезла оттуда, откуда я её не ждал: с ключом, который использовался скриптом генерации картинок. Почему-то на мобильной версии использовался скрипт от главной страницы, а ключи там были разные, так как использовали inode от файла конфигурации. И я полдня возился, прежде чем нашёл это! Но в итоге всё же картинки на WebP перевёл и хоть как-то улучшил показатели и внутренних страниц сайта.
К этому моменту я уже вместо радости по поводу того, что удалось сделать пусть даже и отдалённый закоулок Интернета легче и быстрее, а значит, сделать шажок к своему идеалу «дружелюбный мир для бедных», стал испытывать злость по поводу того, что никак не могу закончить и вернуться к своим основным задачам: прохождению курса по информаицонной безопасности и разработке MLFW. Но увы, злоключения на этом не кончились. Оказалось, когда я переносил оптимизированный запрос с мобильной версии сайта на основную, я закомментировал оба: и старый, и новый. Но вместо того, чтобы просто вырубить сайт с какой-нибудь ошибкой или просто пустым экраном, это породило весьма неожиданный баг: в карточке товары показывались по одной цене, а в корзину попадали по другой. (В этом магазине в своё время сделали очень кривое решение: в базе хранят оптовую цену, а розничную считают в скрипте, причём код скопипастили в несколько разных мест, поэтому периодически такие проблемы всплывают.)
На исправление этого ушла минута. Но проблема в том, что оптимизацией я занимался ночью, утром ушёл спать, и сообщение об этой ошибке прочитал только вечером, когда сайт уже часов пять провисел в таком состоянии.
Ну и сегодня заказчики выявили ещё одну проблему: полезли ошибки во взаимодействии со СберМегаМаркетом. Причём, судя по логам, наблюдались они ещё 5 июля, до того, как я затеял все эти переделки. Но такой уж я человек, что мне проще сделать как надо, чем тратить силы на объяснение и доказывание неспециалистам того, что с моими действиями это никак не связано. Там тоже оказалось всё непросто: в МегаМаркете почему-то получение сведений об остатках переключили с feedа на ручное управление, где они благополучно обнулились, и переключить обратно не получалось. Пришлось писать в техподдержку, где тоже подтормаживали, и только через 20 минут проблема вроде бы решилась. По крайней мере, у товаров статус поменялся на «в продаже».
В общем, из-за всего этого только сегодня возвращаюсь к нормальной жизни, хотя изначально думал, что ещё в воскресенье смогу почувствовать себя свободным человеком. Опять жизнь в состоянии вечного опоздания…

Большая прогулка в Кузьминки

4X_Pro
Опять не успеваю писать в блог обо всём. Слишком уж быстро несётся поток жизни…
В четверг выполнил давнее желание (возникшее ещё в апреле) — выбрался на прогулку в лесопарк Кузьминки. Кузьминки и Сокольники — это два «заколдованных» места, которые, на первый взгляд, совсем рядом, но каким бы способом я ни выбрал добираться до них, получается долго и неудобно. И даже строительство БКЛ ничего не изменило (хотя, возможно, когда откроют подземную пересадку на Авиамоторной, станет проще).
Какой же это парк огромный! А система прудов вообще кажется бесконечной! В итоге прогулка получилась вполне в духе Истинных времён — почти на полдня.
В парк зашёл на это раз не со стороны Кузьминок, а со стороны Волжской. Выполнил своё давнее желание — пройти вдоль реки Пономарки aka Чурилихи в её нижнем течении до Шибаевского пруда. Пономарка чуть более полноводная, чем Серебрянка, а вода в ней более рыжего цвета. Причём ближе к пруду река течёт в низине с достаточно крутыми склонами, а берега — весьма болотистые, пройти бывает сложно.
Сам Шибаевский пруд — самое шумное и многолюдное место в парке. Поэтому возле него я долго задерживаться не стал, а поскорее пошагал к Щучьему пруду. Вот там реально спокойно и хорошо! А ещё пруд необычно соединён со всеми остальными: хотя он находится рядом с нижней оконечностью Нижнего Кузьминского пруда, к нему идёт канал от самой верхней части этого пруда. Причём возле впадения в Щучий канал разделяется на две части, образуя островок, попасть на который можно по двум деревянным мостам. Впрочем, большое количество таких деревянных мостов — это ещё одна особенность данного парка.
От Щучьего пруда я прошёл вдоль этого канала к Верхнему Кузьминскому пруду. В какой-то момент даже хотел обойти его целиком. Потом прошёл немного дальше, увидел, что пруд гораздо больше, чем кажется от плотины, и понял, что такая прогулка будет слишком уж большой. Хотя в 2015 году я его таки обходил! Вместо этого ограничился тем, что дошёл до здания Конного двора (наверное, самый узнаваемый объект во всём парке) и каменного моста чуть подальше за ним. Мост сильно напоминает те, что есть в Царицыно, но выглядит гораздо более старым.
Потом свернул в лес, какое-то время поблуждал там в надежде найти что-нибудь интересное, и просто лучше изучить эту часть парка, в которой прежде был только один раз, и то зимой. Но ничего особо примечательного на глаза не попалось, зато понял, что нужно уже возвращаться. Сделав небольшую петлю, вышел обратно к плотине между Верхним и Нижним Кузьминскими прудами, а оттуда — к главной усадьбе. Кстати, прежде я как-то всегда проходил мимо, и даже не знал, где именно она находится. А от усадьбы уже отправился домой. Надо будет как-нибудь выбраться ещё раз осенью, если, конечно, получится после переезда.
По дороге обратил внимание на то, что несмотря на все стереотипы от Юго-Восточном округе, часть района Кузьминки возле лесопарка производит впечатление весьма уютного и приятного для жизни места.
Во время прогулки я снял столько фото, что стало ясно, что в лимит из 10 снимков в Instagram я никак не умещусь, поэтому выложил их ВКонтакте:

Заметка в Instagram от July 03, 2023 at 11:28PM

4X_Pro
Продолжаю прогулки по Москве. Вчера выбрался на Чистые пруды. С этим местом у меня связано очень много воспоминаний в период с 2007 по 2019 годы. А вот потом как-то перестал бывать, только в прошлом году проехал на самокате по Бульварному кольцу.
До места добрался только вечером, когда уже стемнело. Но в целом так получилось даже лучше: не так многолюдно, и больше ощущается атмосфера этого удивительного места. Прошёл вокруг пруда, потом подумал, не сходить ли пешком до Китай-города или Таганской, но всё же не решился на такое, и вернулся обратно к одноименной станции метро.
Во время прогулки ушёл в размышления о том, что бардак в моей жизни вызван тем, что никак не могу свести воедино четыре разных представления о своём идеальном Я. Описать их можно так:
1️⃣«Школьник на вечных каникулах», который легко и беззаботно катится по жизни, чтобы получать от неё удовольствие.
2️⃣«Городской монах» — тот, кто избавился от статусных потребностей и умеет довольствоваться малым в материальном плане, и личным примером показывает окружающим, что можно жить, не гонясь за «успехом».
3️⃣«Строитель информационного коммунизма», который создаёт те или иные виды контента, чтобы выложить его во всеобщее пользование под свободной лицензией назло баблорубам, стремящимся коммерциализировать всё и вся.
4️⃣«Изобретатель и человек многих знаний», человек, умеющий решать совершенно разные проблемы, что-то вроде инженера Сайруса Смита из «Таинственного острова».
Но проблема в том, что без внутренних противоречий между собой совмещаются только максимум два каких-либо образа из четырёх описанных. Но и выбрать два каких-то и отказаться от остальных — тоже не получается, хотя пробовал не раз.
#москва #чистыепруды #москвавечером #вечерняяпрогулка #размышления #размышленияожизни #размышленияосебе

Смотреть все фото

Ещё одно разочарование: Epycion

4X_Pro
Нашёл вчера ещё один Fediverse-клиент под названием Epicyon. Сначала понравился: он позиционируется как легковесный (насколько это слово вообще применимо к Python), быстрый движок для небольших сообществ, работающий без JS и даже в консольных броузерах. В общем, как раз то, каким и должен быть софт. В какой-то момент даже подумал, а не запустить ли на нём предварительную версию сообщества идеалистов (да ещё и с готовой интеграцией в Fediverse), пока не напишу свой движок.
Но когда попытался запустить, наступило разочарование. Во-первых, как выяснилось, заставить его работать на нестандартном порту без SSL — задача весьма непростая. Но гораздо хуже другое: незалогиненному пользователю на главной вообще ничего не показывается, кроме краткого описания сообщества. И самое плохое — автор, похоже, был каким-то privacy-озабоченным (чего стоит только фраза «The administrator of this instance does not agree to participate in human subjects research, or research to study website policies and practices, carried out by academic institutions or their executors without prior written consent.» в описании сообщества по умолчанию) и сознательно по умолчанию заблокировал индексацию сообщества поисковыми системами. И если бы я не наткнулся в одном из readme-файлов на упоминание об этом, то мог бы долго недоумевать на тему «а чего это меня не индексируют».
Была мысль поднять виртуальную машину и сделать всё как надо, даже сертификат от Let's encrypt получить. Но тут понял, что для виртуализации в целях потестировать то или иное ПО лучше подходит всё же VIrtualBox, чем QEMU. Во-первых, там есть динамически растущие диски, а во-вторых, при клонировании виртуальной машины можно сделать связанный диск, то есть на диске новой машины будут записываться только изменения по сравнению с основной. Это даёт возможность держать машину с почти чистым дистрибутивом, а перед каждым экспериментом делать такой связанный диск. А QEMU диск клонируется целиком. Причём если делать маленький (я для Alpine сделал 4 Гб изначально), его может просто не хватить (как вчера было с Foremом). Ну и плюс от частого копирования целых гигабайт износ SSD получается слишком большой.

Запустил Forem и разочаровался

4X_Pro
Всё-таки у меня получилось запустить forem на виртуалке. Опять всё шло очень и очень непросто. Сначала забыл создать .env-файл, поэтому в процессе сборки образа возникали ошибки. Потом, когда это обнаружил, вылезла другая ошибка — Blocked host. Долго ничего не мог с ней сделать, потом нашёл какую-то статью, в которой давалось решение именно в случае запуска Ruby on Rails-приложения в docker. Но и то до сих пор до конца не понимаю, как именно это сработало.
После этого с диким скрипом и скрежетом (пусть и воображаемым) главная страница сообщества на Forem всё же открылась! Ну и прожорливый же он! На диске занял 6.6 Гб, оперативки я выделил 2 Гб, занята почти вся, и ещё 300 Мб swap используется. И при этом всё еле ворочается! Правда, возможно, дело было в том, что в качестве среды выполнения по умолчанию используется development, а не production, так как сообщества в Сети работают быстрее.
После установки возникла другая проблема: не пришёл Email для подтверждения пользователя. К счастью, я смог найти код активации в логе, который выводится при работе сервера, а URL подобрать почти методом тыка (точнее, покопался в исходниках). После этого я наконец-то вошёл в своё сообщество уже как полноправный пользователь. Но и тут «приключения» не закончились. Во-первых, по каким-то причинам не подгружаются JavaScripts. А во-вторых, база изначально заполнена тестовыми данными, поэтому мой пользователь оказался не первым и не получил админских прав.
В общем, нужно всё-таки писать свой движок сообщества, на PHP, простой и лёгкий.

Необычная настолочная встреча

4X_Pro
Опять меня несёт потоком жизни куда-то мимо. Вчера плохо выспался, под вечер голова не соображала от слова совсем. Решил лечь пораньше. И даже сумел реализовать это решение — лёг в 0:35. Но получилось как всегда: проспал один цикл, и потом почти восьми утра не мог заснуть повторно. Естественно, днём проснулся очень поздно, делать уже ничего не хотелось.
Вечером наконец-то добрался до настольных игр. Изначально хотел сделать это ещё две недели назад, но всё как-то не складывалось. Такое ощущение, что высшие силы как-то неохотно пускали меня на них. И сегодня, пока добирался, всё время попадал к уходящему поезду метро, на который не успевал, что я считаю весьма неблагоприятным знаком.
Игры сегодня получились необычные. Во-первых, собралось довольно много народа: в опросе отметилось около 30 человек. Причём многие из тех, кто ходил на самые ранние встречи 2018-2019 годов.
Сам я добрался очень поздно — около 21 часа с небольшим. В «японский бэнг» aka Меч Самурая на тот момент народ давно собрался, мест не было. Присоединился к небольшой группе из трёх человек, которая стала играть в игру The Mind. Игра мне очень сильно не понравилась: вроде и задача простая (избавляться от карт по возрастанию чисел на них), но играть нужно не друг против друга, а всем вместе на общую победу. По сути, всё сводится к прогнозированию риска того, что кто-то положит слишком большую карту слишком рано, когда у кого-то ещё есть меньше. Но при этом каким-либо образом согласовывать действия или обмениваться информацией нельзя. По идее, тут может помочь теория вероятности, но не сильно. (Например, была ситуация, когда я положил подряд карты 74 и 76, а у одного из игроков оказалось 75, или когда у меня было 98, а у другого игрока — 99, хотя сами по себе эти события достаточно маловероятны с учётом того, что всего карт 100.) А также время реакции других игроков, которое я вообще никак не учитывал,  Поэтому мои ходы окружающие воспринимали как странные, и Яр.Ш.  стал меня троллить на тему, что у меня гуманитарный склад ума, поэтому играть со мной невозможно. Я тогда на него сильно обиделся, хотел даже поконфликтовать, но как-то не сложилось.
Потом присоединился Дж.П., а ещё один участник ушёл домой. Сыграли в Каркассон, причём не обычный, а в «Охотников и собирателей», где правила немного отличаются. (Я в него до этого играл как-то один раз то ли осенью, то ли зимой.) Я очень переживал, что если проиграю, Яр.Ш. затроллит меня окончательно. Но повезло: удачно занял поле в центре, за которое в конце получил 22 очка (и очень повезло, что пришёл нужный кусок карты), и ещё одну из речных систем, которая дала 10 очков. Ну и остальное набирал лесами и реками по ходу игры. В итоге занял второе место (Яр.Ш. был, кажется, третьим), после чего вполне успокоился.
Потом перегруппировались: часть присутствующих ушла играть в CodeNames, часть присоединилась к нам, Дж.П. ушёл играть в «Колонизаторов». Причём в «японский бэнг» сыграли пару раз вшестером — это самый небалансовый вариант игры, где все атакуют самурая, так как у него умножаются победные очки. И тут отличилась Ал.С.: она убедила всех, что играет за ниндзя, но реально была самураем. В итоге жёлтая команда убедительно победила. На следующий раз сёгуном был я. Игра шла хорошо, но никак не удавалось понять, где кто. В итоге проиграли 8:10:9. Потом сыграли ещё, кажется, раза три, но уже всемером, где игра более сбалансирована (к нам присоединилась Liu Art, а с ней вместе играл ещё один участник). Эти игры запомнились меньше, плюс ещё стала сказываться духота и нехватка кислорода. Помню только, что пару раз мы побеждали с перевесом всего в одно очко.
В общем, домой поехал вполне довольный. Попал немного под дождь, но промок не сильно. А вот весь остаток дня опять ушёл куда-то мимо.

Минимум позади и возвращение к идее каталога бесплатностей

4X_Pro
Кажется, выбрался из биоритмического минимума. Вчера вернулся к работе над фреймворком и достаточно неплохо продвинулся: переделал систему работы с событиями на совместимую с PSR-14, предусмотрел возможность навесить обработчики событий на типичные exceptions, и ещё несколько мелочей доработал. А сегодня опять хватаюсь то за одно, то за другое. С подачи 10geek стал проходить на Stepik курс по «белому хакерству».Наткнулся там на массу полезных материалов, один из которых привёл меня на проект Start.Me — редактируемую онлайн-стартовую страницу, во многом перекликающуюся с моей давней идеей инфохаба.
Но оказалось, что стартовых страниц там можно создавать не одну, а целых три, с разными правами доступа, вплоть до полностью публичных и открытых для индексации. Пришла в голову мысль воспользоваться этим и разместить там временную версию своего каталога бесплатностей Интернета. Конечно, по сравнению с тем, каким я задумывал собственный скрипт, получится очень урезанно, но зато это будет хоть что-то работающее уже сейчас, а не через несколько лет. Так что завтра займусь переносом ссылок из локального файла. Заодно и структуру лучше продумаю в процессе.

Экспериментирую с OpenLLM

4X_Pro
Сегодня наткнулся на проект OpenLLM, который создаёт единый API для работы с разными языковыми моделями и решил с ним поэкспериментировать. В целом впечатления не очень: при использовании русского языка в ответе получается сплошная шизофазия. На английском более-менее приемлемые результаты дают модели opt и dolly-v2 (но последняя работает ужасно долго). Но места на диске и оперативки всё это потребляет просто огромное количество! Впервые после покупки нового компьютера столкнулся с угрозой зависания из-за её нехватки (правда, параллельно висел в памяти броузер с десятком вкладок, VS Code, и World of Tanks).
В общем, на хостинг такое не повесишь, да и держать постоянно на своём компьютере (скажем, для каких-нибудь скриптов) тоже как-то слишком затратно. Так что это разве что поставить поиграться, и не более того.
Но вообще, нужно будет как-нибудь вернуться к идее автоматизации соционического типирования по текстам, но теперь уже с помощью таких вот языковых моделей, а не того подхода, который я использовал в 2016 году.

Первый знак Мастер в World of Tanks!

4X_Pro
Сегодня в World of Tanks день начинался ну очень неудачно: проигрыш за проигрышем. Порой складывается впечатление, что стоит активировать «личные резервы» (бонусы к опыту по итогам боя), как ВБР начинает играть против меня. Или тут дело в том, что в Трансёрфинге называют избыточном потенциалом важности — растут ожидания от боя, поэтому итог оказывается обратный. Когда срок действия резерва истёк, ситуация несколько наладилась: результаты остались так себе, но я хотя бы выполнил три основных дневных задачи. Осталась бонусная — нанести урон 25 единицам техники противника. На обычных танках я бы за такое не взялся, но на арте — это вполне реальная задача. Начал выполнять. И в последнем бою показал какой-то просто запредельный результат: знак «Мастер», 8 единиц повреждённой техники (и, как следствие, медаль «Поддержка»), с отличием выполнена последняя задача кампании «Долгожданное подкрепление» (которую я не мог пройти уже не помню сколько) и эта самая бонусная задача. Ещё использовался бонус «опыт x5», в реультате чего я получил более 4000 опыта.

Заметка в Instagram от June 24, 2023 at 11:40PM

4X_Pro
Так получилось, что ближайшие несколько недель проведу в Москве. Воспользовавшись этим, решил возобновить прогулки по тем местам, где перестал бывать, когда началась пандемия. И начать решил с парка Зарядье, потом отправился пешком до Третьяковской. Там меня ждало небольшое, но удивительное открытие: прямо посреди города в фонтане, несмотря на его малую глубину, во всю плескалась утка и совершенно не боялась людей! Интересно, куда она прячется на ночь?
Во время прогулки размышлял над вопросом, правильно ли я поступаю, что переселяюсь жить в Область. Москва — благоустроеннее, но зачастую — даже слишком, и это начинает восприниматься как что-то искусственное. Особенно сильно это чувствуется как раз в Зарядье: вроде и уголок природы в городе, но какой-то ненастоящей, подходящей лишь для тех, у кого нет возможности выбраться в настоящий лес. Тогда как в Области у меня, наоборот, возникает чувство «вот это и есть настоящая жизнь».
С другой стороны, в Москве сложно заскучать: можно целыми днями бродить по разным местам, созерцать жизнь города, и бывают всякие бесплатные выставки, лекции и тому подобное. Но всё это хорошо летом и тогда, когда нет никаких срочных целей и задач, и можно позволить себе встать из-за компьютера и отсутствовать дома целый день. А вот осенью и зимой — слишком мрачно, серо и скучно.
Наверное, мне следовал бы жить так: с января по середину апреля — в Области, потом — на даче до дня солнцестояния, до сентября — в Москве + путешествия по другим городам, сентябрь-октябрь — снова в Области, и в конце октября уезжать во Владикавказ, где более солнечно и сокращение светового дня переносится не так тяжело. И на новогодние праздники — ненадолго снова в Москву. Но увы, слишком уж такое экономически неэффективно…
#москва #жизньвмоскве #зарядье #река #москварека #мост #мосты #видсмоста #размышления #размышленияожизни

Смотреть все фото

Задать вопрос

Здесь можно задать мне вопрос или спросить совета по любой теме, затронутой в блогах или на форуме. После того, как я отвечу, вопрос и ответ появятся в соответствующем разделе. Но не забываем, что я — сторонник slow life, поэтому каких-либо сроков ответов не обещаю. Самые интересные вопросы станут основой для новых тем на форуме или записей в блоге.
Сразу предупреждаю: глупости, провокации, троллинг и тому подобное летит прямо в /dev/null.