Секреты, которые лучше не трогать… но это не точно
Нет ничего лучше (и более стимулируещего), что бы познакомиться с чем-то новым, как неработающий прод...ведь, да?
------------
Тележка пикнула бодрым: "Привет, у нас сайт недоступен из-за сертификата".
Быстренько глянул на проблемный сертификат. Убедился, что это let's encrypt и, лихо отрапортовав: "Давай рута, там делов на 5 минут", приступил к задачке на 5 минут.
Там делов на 5 минут
Там делов на 5 минут
Там делов на 5 минут
ТАМ ДЕЛОВ НА 5 МИНУТ
Все же знают эту магическую фразу, да?
Да, ожидаемо, там оказалось делов не на 5 минут.
------------
На сервере, не особо задумываясь, делаю привычное движение руками -
Выяснив, что супостат этот docker, да ещё и в режиме swarm, что для меня совсем новьё, откладываю мысль о том, что бы полазить в докере на потом. Не то что бы не могу, но это прод, а черного пояса по devops у меня нет, да он ещё и в режиме роя. Ну его нахер.😰
Решаю, что сначала надо получить сертификат.
Пробую
Тут меня посещает отличная мысль - надо сгенерировать сертификат на другой машине - изи-пизи!
Но и тут ждало разочаровнаие. А что бы убедиться, что ситуация усугубляется, я спросил у гугола, я спросил у яндекса, я спросил у знающих человеков - а можно ли сгенерировать сертификат на чужой машине? И, надо сказать, что гуголы/яндексы сказали правду - сгенерировать сертификат на чужой машине, без прямого доступа к DNS - нельзя, а вот человек, который меня уверял, что "да это фигня, я так тыщу раз делал", оказался не прав.🤌
И тут приходит осознание, что назревает вызов.
В голове вырисовывается план, которого, разумеется, будем придерживаться:
- положить веб-сервер и высвободить 80 порт;
- сгенерировать новый сертификат;
- заменить сертификат;
- запустить веб-сервер с новыми сертификатами;
Всё бы хорошо, но пугающие docker swarm и прод заставляют много думать, потеть и грызть ногти.
Хотя, с другой стороны, что я прод ни разу не клал что ли...
И на этой оптимистичной ноте я полез в docker с немытими руками...
В итоге всё оказалось не так страшно, как думалось. А думалось сначала в сторону🤪
И шаг за шагом к цели:
- снял с публикации порты 80/443
- сгенерировал новый сертификат
- вернул порты на место
- сгенерировал новые секреты для docker
- заменил секреты
Ииии...чуда не произошло. Таргеты для секретов, брал из конфига docker-compose, который лежал рядышком, но оказалось, что конфиг не актуальный😮 , а для деплоя используется ansible, к которым доступа нет.
Пришлось копнуть глубже и поизучать секреты:
И уже, наконец, сделал правильные апдейты новых секретов.
К чему я это всё - а что б не забыть!💪
#backend #devops #docker #docker_swarm #разработка
Нет ничего лучше (и более стимулируещего), что бы познакомиться с чем-то новым, как неработающий прод...ведь, да?
------------
Тележка пикнула бодрым: "Привет, у нас сайт недоступен из-за сертификата".
Быстренько глянул на проблемный сертификат. Убедился, что это let's encrypt и, лихо отрапортовав: "Давай рута, там делов на 5 минут", приступил к задачке на 5 минут.
Там делов на 5 минут
Там делов на 5 минут
Там делов на 5 минут
ТАМ ДЕЛОВ НА 5 МИНУТ
Все же знают эту магическую фразу, да?
Да, ожидаемо, там оказалось делов не на 5 минут.
------------
На сервере, не особо задумываясь, делаю привычное движение руками -
certbot --nginx renew и получаю первый отлуп. Не могу, говорит certbot, обновить сертификат - 80 порт занят каким-то супостатом.Выяснив, что супостат этот docker, да ещё и в режиме swarm, что для меня совсем новьё, откладываю мысль о том, что бы полазить в докере на потом. Не то что бы не могу, но это прод, а черного пояса по devops у меня нет, да он ещё и в режиме роя. Ну его нахер.
Решаю, что сначала надо получить сертификат.
Пробую
certbot с различными флагами - херушки-воробушки. Нужен 80 порт. Тут меня посещает отличная мысль - надо сгенерировать сертификат на другой машине - изи-пизи!
Но и тут ждало разочаровнаие. А что бы убедиться, что ситуация усугубляется, я спросил у гугола, я спросил у яндекса, я спросил у знающих человеков - а можно ли сгенерировать сертификат на чужой машине? И, надо сказать, что гуголы/яндексы сказали правду - сгенерировать сертификат на чужой машине, без прямого доступа к DNS - нельзя, а вот человек, который меня уверял, что "да это фигня, я так тыщу раз делал", оказался не прав.
Тут стоит отметить, что раньше не задумывался как работает утилита, но оказалось, что для обновления сертификатов ей нужен 80 порт или доступ к зоне DNS.🫠
И тут приходит осознание, что назревает вызов.
В голове вырисовывается план, которого, разумеется, будем придерживаться:
- положить веб-сервер и высвободить 80 порт;
- сгенерировать новый сертификат;
- заменить сертификат;
- запустить веб-сервер с новыми сертификатами;
Всё бы хорошо, но пугающие docker swarm и прод заставляют много думать, потеть и грызть ногти.
Хотя, с другой стороны, что я прод ни разу не клал что ли...
И на этой оптимистичной ноте я полез в docker с немытими руками...
В итоге всё оказалось не так страшно, как думалось. А думалось сначала в сторону
killall -9 docker И шаг за шагом к цели:
- снял с публикации порты 80/443
docker service update --publish-rm 80:80 service_name
docker service update --publish-rm 443:443 service_name
- сгенерировал новый сертификат
certbot certonly -d example.ru -d example.ru
- вернул порты на место
docker service update --publish-add published=80,target=80 service_name
docker service update --publish-add published=443,target=443 service_name
- сгенерировал новые секреты для docker
docker secret create fullchain-2025-12 fullchain.pem
docker secret create privkey-2025-12 privkey.pem
- заменил секреты
docker service update \
--secret-rm fullchain \
--secret-rm privkey \
--secret-add source=fullchain-2025-12,target=fullchain \
--secret-add source=privkey-2025-12,target=privkey \
service_name
Ииии...чуда не произошло. Таргеты для секретов, брал из конфига docker-compose, который лежал рядышком, но оказалось, что конфиг не актуальный
Пришлось копнуть глубже и поизучать секреты:
docker service inspect service_name --format '
{{range .Spec.TaskTemplate.ContainerSpec.Secrets}}
secret: {{.SecretName}}
target: {{.File.Name}}
---
{{end}}'
И уже, наконец, сделал правильные апдейты новых секретов.
К чему я это всё - а что б не забыть!
#backend #devops #docker #docker_swarm #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Подруга подкинула проблем...
И да, спасибо группе "2ва Самолёта", за максимально релевантное название, неожиданно случившегося опыта.🤔
Кто работает с laravel знает, или по крайней мере, догадывается, что в ней (или в нём?) есть всё, собственно как и в Греции. Сегодня хочу рассмотреть один такой момент, который, как мне кажется, довольно интересный, а именно использование трейта softDeletes и не самая очевидная его особенность.
Нацепив на модель трейт softDeletes, мы её награждаем полем
Итак, всё, вроде бы, круто - данные сохранили, индексы, для +10 к скорости выборки, добавили. При использовании ORM удалённые записи не возвращаются в запросах, model-route-binding тоже сыпит 404 ошибкой при обращении к удалённым записям. Всё хорошо!
Хорошо-хорошо, да не очень-то...
Для меня стало неожиданным сюрпризом, что в правилах валидации, таких как😭 . Да, блин! В правилах валидации требуется явное указание, что нужно исключать записи, помеченные на удаление, например так:
Laravel весь такой магический, что волей-неволей приучает нас, что везде ожидается одинаковое поведение, но суровая жопа реальности сказала, что магии не существует! Самое обидное, что в основной документации об этом ни слова, но, справедливости ради, есть в API документации.
Почему такая несправедливость?
Потому что softDeletes является частью мира ORM и представляет собой глобальный скоуп. В то время как валидаторы - это прямые запросы к БД и ни про какие ORM и scope слыхом не слыхивали.
Что жжжж, ожидание-реальность как оно есть.😮
Учите матчасть!
——
🎶 А пока писал пост заслушал до дыр:
- Дарья Безбородова, Дмитрий Гусаров - Винил
- Дарья Безбородова, Дмитрий Гусаров - Блюз о крыльях, ногах и хвостах.
Просто восторг!
#laravel #softDeletes #php #backend #web #разработка
И да, спасибо группе "2ва Самолёта", за максимально релевантное название, неожиданно случившегося опыта.
Кто работает с laravel знает, или по крайней мере, догадывается, что в ней (или в нём?) есть всё, собственно как и в Греции. Сегодня хочу рассмотреть один такой момент, который, как мне кажется, довольно интересный, а именно использование трейта softDeletes и не самая очевидная его особенность.
Нацепив на модель трейт softDeletes, мы её награждаем полем
deleted_at, в результате чего запись из БД не удаляется физически, а помечается на удаление - deleted_at становится не null. Это полезно, если мы хотим сохранить данные для какого-то аудита или защитить данные от случайных приступов криворукости.Стоит отметить, что сам по себе трейт не создаёт поле deleted_at и не добавляет соответствующих полей в БД. Поля для БД необходимо предусмотреть на этапе проектировния таблицы и указать явно в миграции $table->softDeletes() и, лучше добавить по полю индекс.
Пупупупупу-у-у-у! А у меня ж индексы везде стоят? Ведь да же?..😰
Итак, всё, вроде бы, круто - данные сохранили, индексы, для +10 к скорости выборки, добавили. При использовании ORM удалённые записи не возвращаются в запросах, model-route-binding тоже сыпит 404 ошибкой при обращении к удалённым записям. Всё хорошо!
Хорошо-хорошо, да не очень-то...
Для меня стало неожиданным сюрпризом, что в правилах валидации, таких как
exists и unique, эта магия не работает Rule::exists(PromoCode::class, 'code')->withoutTrashed();
Laravel весь такой магический, что волей-неволей приучает нас, что везде ожидается одинаковое поведение, но суровая жопа реальности сказала, что магии не существует! Самое обидное, что в основной документации об этом ни слова, но, справедливости ради, есть в API документации.
Почему такая несправедливость?
Потому что softDeletes является частью мира ORM и представляет собой глобальный скоуп. В то время как валидаторы - это прямые запросы к БД и ни про какие ORM и scope слыхом не слыхивали.
Что жжжж, ожидание-реальность как оно есть.
Учите матчасть!
——
- Дарья Безбородова, Дмитрий Гусаров - Винил
- Дарья Безбородова, Дмитрий Гусаров - Блюз о крыльях, ногах и хвостах.
Просто восторг!
#laravel #softDeletes #php #backend #web #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🔥1
Что ж, 2025‑й честно старался, но не справился и мы выстояли.
Значит, всё было не зря.
С Новым годом и с новыми силами!🎅
Значит, всё было не зря.
С Новым годом и с новыми силами!
Please open Telegram to view this post
VIEW IN TELEGRAM
2025: 1813 часов за клавиатурой и другие итоги года
Пока идут длинные выходные, можно устроить небольшое ретро на прошедшие 365 дней. Раньше я такого не делал, так что не судите строго, братцы!
👩💻 Fullstack
Начнём с основной деятельности - благо, её проще отследить благодаря сервису WakaTime.
За год я накодил 1 813 часов - в среднем это 7 часов 20 минут в день. И это только чистое время кодинга: без учёта созвонов, писем, чатов и философских размышлений о смысле жизни.
При этом самый длинный день кодинга длился 12 часов и 51 минуту - видимо, поймал волну🧑💻 .
А самым продуктивным днём недели была среда (потому что в среду мало созвонов?😏 )
В этом году самым востребованными языками у меня были PHP и TypeScript, которые использовались в проектах на Laravel, Yii2, Vue/Nuxt и React/Next. Так же было много:
- SQL,
- Sass/SCSS
- CoffeeScript
- Docker
- Bash
- немного Go и ряд других языков.
По задачам всё довольно буднично: много рутины, но нашлось и несколько интересных кейсов, которые заставили возвращаться к ним по нескольку раз.
📖 Книги
Не осталась обделённой и моя слабость - книги.
За год было прочитано почти 6 кг (5.89 кг, если точнее), что составляет 5 696 страниц или 12 книг.
По жанрам разбивка получилась такая:
- 58% - фантастика,
- 25% - фентези,
- 17% - детектив.
Конечно, хотелось бы читать больше, но кто тогда будет работать? Зато книги действительно читались, а не просто украшали полку.
Ещё я опробовал аудиокниги - формат, честно говоря, не мой. Мне бы страничками пошуршать, ощутить приятную тяжесть в руках да вдохнуть запах типографской краски. Но, возможно, для каких-то случаев, аудиоформат и пригодится. Посмотрим...
💪 Спорт
Дабы окончательно не превратиться в офисный кактус, спорт был со мной на протяжении всего года:
- 114 часов кардио - 684 км, сожжено примерно 45 600 ккал
- 156 часов силовых - 93 600 ккал в минус
До Аполлона, конечно, как до Китая на корячках...
☺️ A ещё...
- 80 285 очков заработал в "зелёной сове", провёл 3 935 минут занятий в 6 языках в течение 397 дней без перерыва;
- посетил IT-конфу за последние много лет и напомнил себе, что айти существует не только в чатах и таск-трекерах;
- накидал простенькую сцену платформера в Unity, дабы запустить немного свежего воздуха в трудовые будни;
- и начал вести этот канал - покоряем новые горизонты.
——
Всё ещё не выгорел и всё ещё интересно.
Значит, можно смело двигаться дальше - в 2026‑й!
#итоги #год_2025
Пока идут длинные выходные, можно устроить небольшое ретро на прошедшие 365 дней. Раньше я такого не делал, так что не судите строго, братцы!
Начнём с основной деятельности - благо, её проще отследить благодаря сервису WakaTime.
За год я накодил 1 813 часов - в среднем это 7 часов 20 минут в день. И это только чистое время кодинга: без учёта созвонов, писем, чатов и философских размышлений о смысле жизни.
При этом самый длинный день кодинга длился 12 часов и 51 минуту - видимо, поймал волну
А самым продуктивным днём недели была среда (потому что в среду мало созвонов?
В этом году самым востребованными языками у меня были PHP и TypeScript, которые использовались в проектах на Laravel, Yii2, Vue/Nuxt и React/Next. Так же было много:
- SQL,
- Sass/SCSS
- CoffeeScript
- Docker
- Bash
- немного Go и ряд других языков.
По задачам всё довольно буднично: много рутины, но нашлось и несколько интересных кейсов, которые заставили возвращаться к ним по нескольку раз.
Не осталась обделённой и моя слабость - книги.
За год было прочитано почти 6 кг (5.89 кг, если точнее), что составляет 5 696 страниц или 12 книг.
По жанрам разбивка получилась такая:
- 58% - фантастика,
- 25% - фентези,
- 17% - детектив.
Конечно, хотелось бы читать больше, но кто тогда будет работать? Зато книги действительно читались, а не просто украшали полку.
Ещё я опробовал аудиокниги - формат, честно говоря, не мой. Мне бы страничками пошуршать, ощутить приятную тяжесть в руках да вдохнуть запах типографской краски. Но, возможно, для каких-то случаев, аудиоформат и пригодится. Посмотрим...
Дабы окончательно не превратиться в офисный кактус, спорт был со мной на протяжении всего года:
- 114 часов кардио - 684 км, сожжено примерно 45 600 ккал
- 156 часов силовых - 93 600 ккал в минус
До Аполлона, конечно, как до Китая на корячках...
- 80 285 очков заработал в "зелёной сове", провёл 3 935 минут занятий в 6 языках в течение 397 дней без перерыва;
- посетил IT-конфу за последние много лет и напомнил себе, что айти существует не только в чатах и таск-трекерах;
- накидал простенькую сцену платформера в Unity, дабы запустить немного свежего воздуха в трудовые будни;
- и начал вести этот канал - покоряем новые горизонты.
——
Всё ещё не выгорел и всё ещё интересно.
Значит, можно смело двигаться дальше - в 2026‑й!
#итоги #год_2025
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Лангр. Сыр, который не прочь побаловать себя игристым
Сегодня хочется рассказать об одной своей слабости - мягком сыре лангр. Захомячив очередную небольшую головку этого сыра, душа просит рассказать о нём миру. Погнали знакомиться...
Что же ты такое
Лангр (фр. Langres) - французский мягкий сыр из коровьего молока со сморщенной корочкой оранжевого цвета. Корочка обычно клейкая и немного влажная. Свой цвет корочка получает за счёт того, что во время созревания сыр протирают рассолом с добавлением оранжевого красителя из семян аннато. А ещё, у головки сыра имеется ямка в верхней части - кто-то называет её короной, а турофилы называют его "фонтаном" (уж не знаю почему🤷♀️ ).
Головки сыра, как правило, делают небольшими - диаметром 7,5 - 9 см, высотой 4 - 6 см и весом около 150 г. На ранней стадии созревания тело сыра может быть упругим (мне такие не попадались ни разу), а с течением времени становится более сливочным и текучим (самый самолёт как по мне😋 ).
Сыр обладает довольно резким запахом (о, да, в холодильнике лучше его не хранить вне закрытых ёмкостей😫 ) и острым, терпким вкусом, который часто сравнивают с копчёным беконом. Говорят, что на ранних стадиях созревания ещё может присутствовать запах луговых цветов.
История и происхождение
Как и многие ремесленные сыры, сыр лангр появился на сельскохозяйственных угодьях на лангрском плато, в честь которого сыр и назван. Изначально его изготавливали фермеры, используя терракотовые ёмкости и свежее тёплое молоко коров. Согласно легенде, фермеры сушили сыр на листьях липы и раскладывали его для созревания на соломе. По некоторым данным, его происхождение восходит к династии Меровингов, правившей в 700 году нашей эры.
Первоначальную популярность сыр снискал у местных монахов, доминиканского аббатства, находящегося в городе Лангр. Один из монахов даже выдумал похвальную песню в честь этого сыра.
В начале ХХ века, популярность сыра резко упала, потому что ремесленные сыры стали вытеснять сыры, производимые на мануфактурах, да и характерный запах считался "деревенским" и грубым, что не придавало ему популярности.
Однако, в мае 1991 года сыр лангр получил сертификат AOC (Appellation d’Origine Contrôlée), который подтверждает его происхождение и стандарты производства. С 2009 года сыр имеет статус Appellation d’Origine Protégée (защищённое обозначение происхождения).
Традиции и особенности🍷
Характерная особенность лангра - это выемка в центре головки, которое образуется из-за того, что во время созревания сыр никогда не переворачивают в результате чего верх головки оседает. Эта особенность породила особый гастрономический обычай: перед употреблением в выемку наливают немного алкоголя: граппы или шампанского и дают сыру пропитаться. Алкоголь делает структуру сыра ещё более сливочной и подчёркивает его вкус.
Ранее в "фонтан" наливали коньяк, чтобы избавиться от мелких жучков, которые могли забиваться в морщинки корочки. Хотя сейчас сыр производится в санитарных условиях и наличие жуков исключено, традиция сохранилась.
А ещё лангр не принято резать на кусочки, его едят ложкой.
Источники: novostioede.ru, tastingtable.com, ruwiki.ru
#внезапно #позновательно #изюм #сыр #лангр
Сегодня хочется рассказать об одной своей слабости - мягком сыре лангр. Захомячив очередную небольшую головку этого сыра, душа просит рассказать о нём миру. Погнали знакомиться...
Что же ты такое
Лангр (фр. Langres) - французский мягкий сыр из коровьего молока со сморщенной корочкой оранжевого цвета. Корочка обычно клейкая и немного влажная. Свой цвет корочка получает за счёт того, что во время созревания сыр протирают рассолом с добавлением оранжевого красителя из семян аннато. А ещё, у головки сыра имеется ямка в верхней части - кто-то называет её короной, а турофилы называют его "фонтаном" (уж не знаю почему
Головки сыра, как правило, делают небольшими - диаметром 7,5 - 9 см, высотой 4 - 6 см и весом около 150 г. На ранней стадии созревания тело сыра может быть упругим (мне такие не попадались ни разу), а с течением времени становится более сливочным и текучим (самый самолёт как по мне
Сыр обладает довольно резким запахом (о, да, в холодильнике лучше его не хранить вне закрытых ёмкостей
История и происхождение
Как и многие ремесленные сыры, сыр лангр появился на сельскохозяйственных угодьях на лангрском плато, в честь которого сыр и назван. Изначально его изготавливали фермеры, используя терракотовые ёмкости и свежее тёплое молоко коров. Согласно легенде, фермеры сушили сыр на листьях липы и раскладывали его для созревания на соломе. По некоторым данным, его происхождение восходит к династии Меровингов, правившей в 700 году нашей эры.
Первоначальную популярность сыр снискал у местных монахов, доминиканского аббатства, находящегося в городе Лангр. Один из монахов даже выдумал похвальную песню в честь этого сыра.
В начале ХХ века, популярность сыра резко упала, потому что ремесленные сыры стали вытеснять сыры, производимые на мануфактурах, да и характерный запах считался "деревенским" и грубым, что не придавало ему популярности.
Однако, в мае 1991 года сыр лангр получил сертификат AOC (Appellation d’Origine Contrôlée), который подтверждает его происхождение и стандарты производства. С 2009 года сыр имеет статус Appellation d’Origine Protégée (защищённое обозначение происхождения).
Традиции и особенности
Характерная особенность лангра - это выемка в центре головки, которое образуется из-за того, что во время созревания сыр никогда не переворачивают в результате чего верх головки оседает. Эта особенность породила особый гастрономический обычай: перед употреблением в выемку наливают немного алкоголя: граппы или шампанского и дают сыру пропитаться. Алкоголь делает структуру сыра ещё более сливочной и подчёркивает его вкус.
Ранее в "фонтан" наливали коньяк, чтобы избавиться от мелких жучков, которые могли забиваться в морщинки корочки. Хотя сейчас сыр производится в санитарных условиях и наличие жуков исключено, традиция сохранилась.
А ещё лангр не принято резать на кусочки, его едят ложкой.
Источники: novostioede.ru, tastingtable.com, ruwiki.ru
#внезапно #позновательно #изюм #сыр #лангр
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤩2
Читальня. Ричард Морган – Видоизменённый углерод
— Возвращение из мёртвых может быть очень мучительным —
Заметили как в последнее время посыпались новости то про лекарства от рака, то про искусственную кровь, то про увеличение средней продолжительности жизни человека, - вот и мировые лидеры в кулуарах обсуждают средний срок жизни в 150 - 170 лет. Некоторые учёные просят не помирать ближайшие 10 лет, потому что скоро наука сможет возвращать тело человека в состояние, как у 20-ти летнего. Глядишь такими темпами и на нашем веку бессмертие заработает.
А вот в мире, созданном Ричардом Морганом, бессмертие уже изобретено и доступноне только лишь всем. При наличии достаточного количества кредитов можно позволить себе прожить не одну сотню лет.
Бессмертие не тела, но разума.
Человечество научилось оцифровывать своё сознание и стало размещать егона дискетах в стеках, которые помещаются в любое подготовленное тело, на которое хватит средств. А тело можно подобрать на любой вкус, и цвет, и кошелёк: на маркетплейсе купить, забрать у другого человека, вырастить, клонировать или надеть синтетическую поделку. В общем, есть варианты.
А средства, как полагается, есть только у богатейших мира сего, а остальным достаётся что осталось, по ОМС.
На этой идее - перемещения сознания в разные тела - и построен роман.
По своей сути Видоизменённый углерод - это нуарный детектив, в антураже жестокого мира будущего, где всем правят технологии и корпорации. Главный герой, Такеши Ковач, пролежав несколько сотен лет в виде стека на полке, был расконсервирован по запросу одного земногоолигарха мафа, по той причине, что тот сам себе пустил пулю в стек (так гласит официальная версия полиции), уничтожив своё сознание. Но маф, считает, что он не такой и решает привлечь к расследованию Такеши Ковача - человека с особым складом ума, способного увидеть невероятное, но очевидное.
События в книге развиваются с бешеным темпом: перестрелки сменяют друг друга, кровь льётся литрами, а тела разлетаются на части - здесь потеря руки или головы не всегда означает смерть, а иногда лишь временное неудобство. В минуты затишья - допросы, разговоры, виртуальная реальность, наркотики, секс и Эдгар Аллан По. Всё это описано жёстко, откровенно, красочно, брутально, но при этом удивительно увлекательно.
Но «Видоизменённый углерод» - это не только детектив и нескончаемые перестрелки. Это книга о цене бессмертия и о мире, где богатые могут позволить себе всё, а бедные - лишь обслуживают хотелки богатеев. Здесь технологии напрямую влияют на религию, политику и социальное неравенство, а вопрос «что такое человек» становится куда сложнее, чем просто наличие тела и сознания.
Итого: отличный бодрый, местами жестокий, детектив о будущем, в котором технологии шагнули далеко вперёд, а вот человечность - совсем не факт.
А какое отношение имеет к этой истории Эдгар Алан По я предлагаю выяснить самостоятельно.
8 "жеребцов" из 10
#книги #почитать #РичардМорган #Морган #ТакесиКовач #ВидоизменённыйУглерод #детектив #киберпанк #нуар #фантастика
— Возвращение из мёртвых может быть очень мучительным —
Заметили как в последнее время посыпались новости то про лекарства от рака, то про искусственную кровь, то про увеличение средней продолжительности жизни человека, - вот и мировые лидеры в кулуарах обсуждают средний срок жизни в 150 - 170 лет. Некоторые учёные просят не помирать ближайшие 10 лет, потому что скоро наука сможет возвращать тело человека в состояние, как у 20-ти летнего. Глядишь такими темпами и на нашем веку бессмертие заработает.
А вот в мире, созданном Ричардом Морганом, бессмертие уже изобретено и доступно
Бессмертие не тела, но разума.
Человечество научилось оцифровывать своё сознание и стало размещать его
А средства, как полагается, есть только у богатейших мира сего, а остальным достаётся что осталось, по ОМС.
На этой идее - перемещения сознания в разные тела - и построен роман.
По своей сути Видоизменённый углерод - это нуарный детектив, в антураже жестокого мира будущего, где всем правят технологии и корпорации. Главный герой, Такеши Ковач, пролежав несколько сотен лет в виде стека на полке, был расконсервирован по запросу одного земного
События в книге развиваются с бешеным темпом: перестрелки сменяют друг друга, кровь льётся литрами, а тела разлетаются на части - здесь потеря руки или головы не всегда означает смерть, а иногда лишь временное неудобство. В минуты затишья - допросы, разговоры, виртуальная реальность, наркотики, секс и Эдгар Аллан По. Всё это описано жёстко, откровенно, красочно, брутально, но при этом удивительно увлекательно.
Но «Видоизменённый углерод» - это не только детектив и нескончаемые перестрелки. Это книга о цене бессмертия и о мире, где богатые могут позволить себе всё, а бедные - лишь обслуживают хотелки богатеев. Здесь технологии напрямую влияют на религию, политику и социальное неравенство, а вопрос «что такое человек» становится куда сложнее, чем просто наличие тела и сознания.
Итого: отличный бодрый, местами жестокий, детектив о будущем, в котором технологии шагнули далеко вперёд, а вот человечность - совсем не факт.
А какое отношение имеет к этой истории Эдгар Алан По я предлагаю выяснить самостоятельно.
8 "жеребцов" из 10
#книги #почитать #РичардМорган #Морган #ТакесиКовач #ВидоизменённыйУглерод #детектив #киберпанк #нуар #фантастика
👍2🔥1
Каждому проекту - домен. Каждому разработчику - покой
- Как забыть про порты в локальной разработке с Traefik -
Docker в нашу разработческую жизнь вошёл всерьёз и надолго. Составление конфигураций, биндинг томов, маппинг портов - стандартная рутина.
И вот о последнем я бы поговорил отдельно... Согласитесь, все эти бесконечные
Посему у меня локально каждый проект имеет своё имя в зоне
Но выход есть - и он называется Traefik🤘
Traefik - мой новый лучший друг в мире Docker. Это обратный прокси-сервер, который отлично понимает docker и берёт на себя всю грязную работу по маршрутизации приложений. Он может многое: балансировку, контроль доступа, HTTPS. Но в контексте локальной разработки мне от него нужна маршрутизация. А приятным бонусом при работе с ним - это возможность установить SSL-сертификат - большего для локальной разработки и не надо.
Принципиальная схема работы выглядит так:
Вся магия в том, что наружу смотрит только Traefik, а сами сервисы живут внутри общей docker-сети.
Как это работает локально:
- поднимаем Traefik в отдельном docker-compose и подключаем его к общей внешней сети;
- все сервисы, работающие по HTTP, размещаем в той же сети;
- вместо проброса портов используем метки (labels) в Docker - Traefik сам найдёт сервисы и настроит маршрутизацию.
Конфиг для сервиса выглядит примерно так:
Ву-а-ля!
Открываем в браузере
Каеф!😎
#docker #traefik #devops #backend #разработка
- Как забыть про порты в локальной разработке с Traefik -
Docker в нашу разработческую жизнь вошёл всерьёз и надолго. Составление конфигураций, биндинг томов, маппинг портов - стандартная рутина.
И вот о последнем я бы поговорил отдельно... Согласитесь, все эти бесконечные
localhost:8081, localhost:4200, localhost:8082 наводят тоску. Наверное, я их даже несколько ненавижу. И дело не только в том, что порты в адресной строке выглядят не гармонично, так они ещё и запоминаются не очень хорошо. А если ещё приходится переключаться между проектами, или проект требует нескольких открытых приложений, то в адресной строке начинается хаос.Посему у меня локально каждый проект имеет своё имя в зоне
.local - ведь, проще запомнить доменное имя, чем порты, особенно, если постоянно переключаешься между проектами. Но выход есть - и он называется Traefik
Traefik - мой новый лучший друг в мире Docker. Это обратный прокси-сервер, который отлично понимает docker и берёт на себя всю грязную работу по маршрутизации приложений. Он может многое: балансировку, контроль доступа, HTTPS. Но в контексте локальной разработки мне от него нужна маршрутизация. А приятным бонусом при работе с ним - это возможность установить SSL-сертификат - большего для локальной разработки и не надо.
Принципиальная схема работы выглядит так:
Browser (service.local)
│
▼
Traefik
│
▼
Docker network
│
▼
App / API / SPA
Вся магия в том, что наружу смотрит только Traefik, а сами сервисы живут внутри общей docker-сети.
Как это работает локально:
- поднимаем Traefik в отдельном docker-compose и подключаем его к общей внешней сети;
- все сервисы, работающие по HTTP, размещаем в той же сети;
- вместо проброса портов используем метки (labels) в Docker - Traefik сам найдёт сервисы и настроит маршрутизацию.
Конфиг для сервиса выглядит примерно так:
services:
app:
image: my-cool-app
networks:
- web
- default
labels:
- traefik.enable=true
- traefik.http.routers.project1.rule=Host(`project1.local`)
- traefik.http.services.project1.loadbalancer.server.port=80
networks:
web:
external: true
Ву-а-ля!
Открываем в браузере
project1.local без всяких бесячих портов. Каеф!
#docker #traefik #devops #backend #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Дорогой дневник, в меня вставили параметры. JsonResource
- Как сломать JsonResource, не ломая JsonResource -
Сегодня хочется поговорить или о немного вредном, или о немного неправильном. О чём-то не по феншую. Не исключаю, что это вообще не lara-way и в приличном чате меня аккуратно, но уверенно запинают ногами!👊
НО, почему бы и нет...
Разрабатывая API на
Чем же он хорош, наверняка, не спросите вы, но я напомню:
— скрывает истинную структуру модели,
— определяет контракт ответа,
— позволяет добавлять вычисляемые поля,
— форматирует данные.
И вот про модификацию ответа в зависимости от непреодолимых внешних факторов, я и хочу поговорить.
Сам
И тут из зала: "Йо! Мэн! Создай отдельный ресурс и не делай нам мозги!".
Что ж. Справедливо.
Но плодить новые сущности из-за пары флагов - право, не хотелось.
Другие знатоки скажут: "Чел! Добавь атрибутов к реквесту!".
Да, почему бы и не атрибуты:
Тоже решение, но выглядит громоздко, и плохо документируется.
Мы пойдём другим путём!
Сначала попробовал расширить конструктор:
Но это работает только для единичного ресурса, а вот для коллекции - облом. А ещё ресурс нужно создавать вручную, а не через фабрику — не наш метод — я фабрику люблю.
В итоге после нескольких экспериментов получился универсальный
А ещё, добавляя свойства ресурса, и документируется неплохо.
Да. Не по учебнику.☝️
Но и, вроде бы, не совсем криминал, и даже может быть полезным.
В общем, на будущее, в чердачок, решение это отложил.
#эксперименты #laravel #backend #web #разработка
- Как сломать JsonResource, не ломая JsonResource -
Сегодня хочется поговорить или о немного вредном, или о немного неправильном. О чём-то не по феншую. Не исключаю, что это вообще не lara-way и в приличном чате меня аккуратно, но уверенно запинают ногами!
НО, почему бы и нет...
Разрабатывая API на
Laravel, мы постоянно имеем дело с JsonResource.Чем же он хорош, наверняка, не спросите вы, но я напомню:
— скрывает истинную структуру модели,
— определяет контракт ответа,
— позволяет добавлять вычисляемые поля,
— форматирует данные.
И вот про модификацию ответа в зависимости от непреодолимых внешних факторов, я и хочу поговорить.
Сам
JsonResource не должен быть перегружен сложной логикой - и это правильно! Но в моём случае потребовалось извне передать в коллекцию параметры для модификации вывода. И тут из зала: "Йо! Мэн! Создай отдельный ресурс и не делай нам мозги!".
Что ж. Справедливо.
Но плодить новые сущности из-за пары флагов - право, не хотелось.
Другие знатоки скажут: "Чел! Добавь атрибутов к реквесту!".
Да, почему бы и не атрибуты:
$request->attributes->add([
'param1' => 'foo',
'param2' => 'bar',
]);
Тоже решение, но выглядит громоздко, и плохо документируется.
Мы пойдём другим путём!
Сначала попробовал расширить конструктор:
public function __construct($resource, bool $param = false)
{
parent::__construct($resource);
$this->param = $param;
}
Но это работает только для единичного ресурса, а вот для коллекции - облом. А ещё ресурс нужно создавать вручную, а не через фабрику — не наш метод — я фабрику люблю.
В итоге после нескольких экспериментов получился универсальный
JsonResource, в который можно передать несколько параметров и затем их использовать для модификации данных.class JsonResourceWithParams extends JsonResource
{
public static function collectionWithData($resources, $params)
{
return self::collection($resources)->each(function(self $r) use ($params) {
foreach ($params as $param => $value) {
if (property_exists($r, $param)) {
$r->{$param} = $value;
}
}
});
}
}
А ещё, добавляя свойства ресурса, и документируется неплохо.
Да. Не по учебнику.
Но и, вроде бы, не совсем криминал, и даже может быть полезным.
В общем, на будущее, в чердачок, решение это отложил.
#эксперименты #laravel #backend #web #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🤔1
Читальня. Питер В. Бретт – Копьё пустыни
— В Красии ты никчёмен, если никто не пытается тебя убить —
Во втором томе «демонической серии» Питера В. Бретта акцент событий заметно смещается. Если в первой книге главной угрозой были подземники, то здесь на первый план выходит противостояние человека юга и человека севера. Демоны по-прежнему рядом и рыщут в ночи, но теперь эта битва уходит на второй план.
У демонов появляются новые юниты - князья и хамелеоны - лишь они теперь представляют реальную опасность человеку. Остальные представители подземной фауны уже не внушают прежнего ужаса: люди вооружились мечеными копьями, щитами и стрелами, научились создавать плащи невидимки, а города защищают «великие метки», к которым демоны не подходят.
Но главная эскалация происходит не в ночи - а среди людей.
Мы подробно знакомимся с внутренним укладом Красии - общества глубоко религиозного и воинственного, построенного на жёсткой кастовой системе. Через историю становления Ахмана Джардира - Избавителя всея Красии - мы постепенно погружаемся в культуру народа пустыни. Быт описан детально, а мир Красии ощущается цельным и продуманным. В повествование добавляется много новых терминов: шарум, дама'тинг, алагай, шарадж, андрах и т.д. Они сначала сбивают с толку, но со временем начинаешь улавливать логику языка и ориентироваться становится значительно проще.
Убедив себя и свой народ в собственной мессианской роли, Джардир отправляется на север объединять человечество и готовить его к последней битве с демонами. И его не остановит тот факт, что объединение придётся проводить огнём и мечом. Через кровь, насилие и террор - к высшей цели.
И здесь сталкиваются не только народы, но и Избавители. Каждый со своей правдой и собственными убеждениями в то, как именно нужно спасать мир от подземной напасти.
На фоне религиозной экспансии, политических амбиций и военных походов появляются и любовные линии - некоторые весьма неожиданные. Они не размывают основной конфликт, а наоборот, добавляют истории живости и эмоционального напряжения.
Так же не забыты и второстепенные персонажи: очень интересен хаффит Аббан, который как то самое ружьё, которое обязательно выстрелит. Мать Лиши, Элона, - очень противоречивая дама, но весьма прямолинейна и точна в своих суждениях; отпрыски Джардира, которым тоже, судя по всему, отведено не последнее место в будущих книгах, а ещё Гаред, Кендалл, королевские особы...список довольно внушительный и у каждого своя история.
Итог: отличный сиквел, который продолжает первую книгу и расширяет мир. Однозначно читать!
9 шарумов из 10
#книги #почитать #ПитерВБретт #Бретт #ВселеннаяМеченого #КопьёПустыни #тёмное #фентези #магия #монстры
— Обзор первой книги - Меченый
— Обзор третьей книги - Дневная битва
— Обзор четвёртой книги - Трон Черепов
— В Красии ты никчёмен, если никто не пытается тебя убить —
Во втором томе «демонической серии» Питера В. Бретта акцент событий заметно смещается. Если в первой книге главной угрозой были подземники, то здесь на первый план выходит противостояние человека юга и человека севера. Демоны по-прежнему рядом и рыщут в ночи, но теперь эта битва уходит на второй план.
У демонов появляются новые юниты - князья и хамелеоны - лишь они теперь представляют реальную опасность человеку. Остальные представители подземной фауны уже не внушают прежнего ужаса: люди вооружились мечеными копьями, щитами и стрелами, научились создавать плащи невидимки, а города защищают «великие метки», к которым демоны не подходят.
Но главная эскалация происходит не в ночи - а среди людей.
Мы подробно знакомимся с внутренним укладом Красии - общества глубоко религиозного и воинственного, построенного на жёсткой кастовой системе. Через историю становления Ахмана Джардира - Избавителя всея Красии - мы постепенно погружаемся в культуру народа пустыни. Быт описан детально, а мир Красии ощущается цельным и продуманным. В повествование добавляется много новых терминов: шарум, дама'тинг, алагай, шарадж, андрах и т.д. Они сначала сбивают с толку, но со временем начинаешь улавливать логику языка и ориентироваться становится значительно проще.
Убедив себя и свой народ в собственной мессианской роли, Джардир отправляется на север объединять человечество и готовить его к последней битве с демонами. И его не остановит тот факт, что объединение придётся проводить огнём и мечом. Через кровь, насилие и террор - к высшей цели.
И здесь сталкиваются не только народы, но и Избавители. Каждый со своей правдой и собственными убеждениями в то, как именно нужно спасать мир от подземной напасти.
На фоне религиозной экспансии, политических амбиций и военных походов появляются и любовные линии - некоторые весьма неожиданные. Они не размывают основной конфликт, а наоборот, добавляют истории живости и эмоционального напряжения.
Так же не забыты и второстепенные персонажи: очень интересен хаффит Аббан, который как то самое ружьё, которое обязательно выстрелит. Мать Лиши, Элона, - очень противоречивая дама, но весьма прямолинейна и точна в своих суждениях; отпрыски Джардира, которым тоже, судя по всему, отведено не последнее место в будущих книгах, а ещё Гаред, Кендалл, королевские особы...список довольно внушительный и у каждого своя история.
Итог: отличный сиквел, который продолжает первую книгу и расширяет мир. Однозначно читать!
9 шарумов из 10
#книги #почитать #ПитерВБретт #Бретт #ВселеннаяМеченого #КопьёПустыни #тёмное #фентези #магия #монстры
🔥1
Cмотря какой fabric, смотря сколько details, очень очень affordable
- Очищающее пламя языкового пуризма -
Итак, с 1 марта 2026 года в России действует закон №168-ФЗ, ограничивающий использование иностранных слов в публичной информации.
Посему в Летудолжнымогут кануть различные sale, кавер, стартап, коучинг и прочие all in.
🇷🇺 Россия
Так-то это не первое подобное законотворчество: в XVIII веке после реформ Петра I появилось много заимствований, в том числе голландских и немецких. Позже, с модой на всё французское в XVIII–XIX веках, в речь массово вошли галлицизмы.
Поэтому Екатерина II При составлении Словаря Академии Российской указывала академикам:
Однако полностью остановить заимствования не удалось.
М. В. Ломоносов придерживался более прагматичной позиции: научные и технические термины следует переводить на русский язык, но если иностранное слово уже получило широкое распространение - бороться с ним бессмысленно.
—
Был как-то на одном проекте коллега, который очень любил "свитчиться между тасками" и слушать это было примерно так же органично, как и знаменитое задорновское "вам чизоф отслайсить?"🤦♂️
—
И, в целом, идея здравая, наверное... но звучать это будет несколько непривычно:
Ну ладно, интернет придумает что-нибудь креативнее✍️
Но вообще языковой пуризм - явление довольно распространённое.
Вот пара особо ярких примеров для ознакомления:
🇮🇸 Исландия
🇫🇷 Франция
Так же элементы языкового пуризма были в Турции, Германии, Хорватии, Венгрии, Великобритании, США и других странах. Явление это не самое редкое, надо сказать.
Обычно оно появляется в ответ на интенсивное проникновение заимствований, которое воспринимается как угроза самобытности и целостности родного языка.
Пуризм особенно активизируется в эпохи формирования национального самосознания или после крупных исторических событий (революций, войн, периодов активной глобализации), когда язык становится символом культурной идентичности.
Ну а пока...
Мёржим, пушим, билдим, фиксим,
Если не упало, – да и фиг с ним!
Фиксим, билдим, мёржим, пушим,
Эй! Кьюэй! Не плюй мне в душу!
©️ Арчет
#внезапно #позновательно #изюм #пуризм
- Очищающее пламя языкового пуризма -
Итак, с 1 марта 2026 года в России действует закон №168-ФЗ, ограничивающий использование иностранных слов в публичной информации.
Посему в Лету
🇷🇺 Россия
Так-то это не первое подобное законотворчество: в XVIII веке после реформ Петра I появилось много заимствований, в том числе голландских и немецких. Позже, с модой на всё французское в XVIII–XIX веках, в речь массово вошли галлицизмы.
Поэтому Екатерина II При составлении Словаря Академии Российской указывала академикам:
В сочиняемом академией словаре избегать всевозможным образом слов чужеземных, а наипаче речений, заменяя оные слова или древними или вновь составленными.
Однако полностью остановить заимствования не удалось.
М. В. Ломоносов придерживался более прагматичной позиции: научные и технические термины следует переводить на русский язык, но если иностранное слово уже получило широкое распространение - бороться с ним бессмысленно.
—
Был как-то на одном проекте коллега, который очень любил "свитчиться между тасками" и слушать это было примерно так же органично, как и знаменитое задорновское "вам чизоф отслайсить?"
—
И, в целом, идея здравая, наверное... но звучать это будет несколько непривычно:
- Константин, яви же порядок деяний, коий изгонит ошибку из серверной обители?
Ну ладно, интернет придумает что-нибудь креативнее
Но вообще языковой пуризм - явление довольно распространённое.
Вот пара особо ярких примеров для ознакомления:
🇮🇸 Исландия
В XIX веке в Исландии началось движение за максимальное избавление языка от иностранных слов, особенно датских, которые использовались в период датского господства. Эта работа продолжалась и в XX веке и активно ведётся до сих пор.
В 1964 году была создана Исландская языковая комиссия, которая вырабатывает рекомендации по сохранению единства и целостности исландского языка. Новые слова создаются на основе древненорвежских или античных корней. Например, слово rafmagn («электричество») буквально переводится как «сила янтаря». Также практикуется придание старому слову нового значения: sími (раньше - «длинная нить») стало означать «телефон».
🇫🇷 Франция
Во Франции пуризм начал формироваться ещё в XVII веке. Основанная в 1635 году Французская академия ставила целью «очистку» языка и продвижение le bon usage — правильного употребления французского. В XX веке борьба за чистоту языка усилилась из-за роста влияния английского языка.
В 1975 году был принят закон Ба-Лорьоля (loi Bas-Lauriol), который обязывал использовать французский язык в рекламе, технических описаниях товаров, трудовых договорах, а радио обязано транслировать минимум 35% песен на французском.
В 1994 году был принят закон Турбона, который ужесточал положения закона 1975 года и регулировал использование иностранных слов.
В настоящее время во Франции действует Комиссия по обогащению французского языка, которая создаёт новые слова для замены англицизмов. Например, вместо английского computer во французском используется ordinateur, вместо fax - télécopie, а вместо e-mail - courriel.
Так же элементы языкового пуризма были в Турции, Германии, Хорватии, Венгрии, Великобритании, США и других странах. Явление это не самое редкое, надо сказать.
Обычно оно появляется в ответ на интенсивное проникновение заимствований, которое воспринимается как угроза самобытности и целостности родного языка.
Пуризм особенно активизируется в эпохи формирования национального самосознания или после крупных исторических событий (революций, войн, периодов активной глобализации), когда язык становится символом культурной идентичности.
Ну а пока...
Мёржим, пушим, билдим, фиксим,
Если не упало, – да и фиг с ним!
Фиксим, билдим, мёржим, пушим,
Эй! Кьюэй! Не плюй мне в душу!
©️ Арчет
#внезапно #позновательно #изюм #пуризм
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Docker разжирел - пора на сушку
- Как не дать docker съесть лишнего -
Случилось страшное - на SSD осталось 60Гб свободного места.
Если не считать, что львиная доля диска занята чем-то не сильно нужным, то😱
Посмотрим, на каких харчах разжирел
—
Время проводить уборку!🛁
—
—
—
—
Или можно заменить всё это одной командой:
В целом, это безопасные команды, но если хочется хардкора и хождения по лезвию бритвы, то можно сделать так: ☢️
Что бы не писать это каждый раз руками, можно в
Или немного улучшим, с лимитом по старости объектов:
И запускаем:
Проводите регулярную чистку и соблюдайте КБЖУ!🍔
#backend #devops #docker #разработка
- Как не дать docker съесть лишнего -
Случилось страшное - на SSD осталось 60Гб свободного места.
Если не считать, что львиная доля диска занята чем-то не сильно нужным, то
docker, разросшийся до 70Гб вызвал оторопь и ужас. Посмотрим, на каких харчах разжирел
docker: —
docker system dfTYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 212 51 51.18GB 20.17GB (39%)
Containers 62 1 337MB 337MB (99%)
Local Volumes 33 6 3.661GB 476.3MB (13%)
Build Cache 2028 0 17.18GB 3.089GB
Время проводить уборку!
—
docker container prune - удаляет остановленные контейнеры,—
docker image prune -a - удаляет все неиспользуемые образы,—
docker builder prune -a - удаляет кэш билдов (иногда именно он жрёт десятки гигабайт),—
docker network prune - удаляет неиспользуемые сетиИли можно заменить всё это одной командой:
docker system prune -a - она почистит контейнеры, образы, build cache и сети разом.В целом, это безопасные команды, но если хочется хардкора и хождения по лезвию бритвы, то можно сделать так: ☢️
docker system prune -a --volumes - и отправить к праотцам ещё и volumes - вместе с базами данных, логами и всем нажитым непосильным трудом.Что бы не писать это каждый раз руками, можно в
~/.zshrc добавить простенький алиас:alias dclean='docker container prune -f && docker image prune -a -f && docker builder prune -a -f'
Или немного улучшим, с лимитом по старости объектов:
dclean() {
local DAYS="${1:-7}"
if ! command -v docker >/dev/null 2>&1; then
echo "docker не найден в PATH"
return 1
fi
echo "== Docker disk usage BEFORE =="
docker system df || return 1
echo
echo "== Pruning stopped containers =="
docker container prune -f || return 1
echo
echo "== Pruning images unused by containers (older than ${DAYS} days) =="
docker image prune -a -f --filter "until=${DAYS}d" || return 1
echo
echo "== Pruning build cache (older than ${DAYS} days) =="
docker builder prune -a -f --filter "until=${DAYS}d" || return 1
echo
echo "== Docker disk usage AFTER =="
docker system df || return 1
}И запускаем:
dclean 14 - удаляет всё старше 14 дней.Проводите регулярную чистку и соблюдайте КБЖУ!
#backend #devops #docker #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1🐳1
По заветам Мюллера, или верить нельзя никому
- Контрразведчик должен знать всегда, как никто другой, что верить в наше время нельзя никому, порой даже самому себе -
TL;DR
А вот ещё был случай...
Задача, в целом, хрестоматийная: берём ссылку на изображение и делаем из неё тумбочку меньшего размера. Казалось бы, что могло пойти не так? Как оказалось - могло.😈
Алгоритм тумбочкования, в принципе, стандартный:
- получаем информацию об оригинальном изображении;
- получаем
-✨ и вуа-ля!
Но в этот раз всё сломал MIME!
Картинка-источник лежала на
Вывод: никогда нельзя доверять
А чтобы всё было по красоте - воспользуемся магией! В частности magic numbers.
Magic numbers - это уникальная, заранее оговорённая, сигнатура файла, записанная в его первых байтах.
И тогда у нас получается быстрая и удобная функция, определяющая тип прям из ДНК файла:
Какие плюсы:
- используем
- если нужно узнать тип файла, допустим, по HTTP, то достаточно скачать первые 256 байт для корректного определения MIME;
Мораль: как учит нас практика - верить нельзя никому. Даже
Будьте бдительны, друзья, и враг не пройдёт!
P.S.: пока писал заметку нашёл ещё хороший вариант, но подходит только для изображений:
Нюансы:
- работает с URL;
- читает только начало файла;
- сразу возвращает MIME изображения;
#эксперименты #backend #web #разработка
- Контрразведчик должен знать всегда, как никто другой, что верить в наше время нельзя никому, порой даже самому себе -
TL;DR
HTTP Content-Type может врать. Если MIME критичен — определяйте тип файла по magic numbers, а не по заголовкам.
А вот ещё был случай...
Задача, в целом, хрестоматийная: берём ссылку на изображение и делаем из неё тумбочку меньшего размера. Казалось бы, что могло пойти не так? Как оказалось - могло.
Алгоритм тумбочкования, в принципе, стандартный:
- получаем информацию об оригинальном изображении;
- получаем
MIME для определения функции создания изображения;-
ImageMagick делает свой magick Но в этот раз всё сломал MIME!
Картинка-источник лежала на
CDN, а тип изображения определялся по HTTP-заголовку Content-Type, который получали при скачивании изображения. И веселью не было предела, когда для обычного jpg сервер внезапно начал возвращать image/png.Вывод: никогда нельзя доверять
HTTP MIME, если MIME на что-то влияет фатально.А чтобы всё было по красоте - воспользуемся магией! В частности magic numbers.
Magic numbers - это уникальная, заранее оговорённая, сигнатура файла, записанная в его первых байтах.
Формат | Magic bytes
PNG | 89 50 4E 47 0D 0A 1A 0A
JPEG | FF D8 FF
GIF | 47 49 46 38
WebP | 52 49 46 46 .... 57 45 42 50
И тогда у нас получается быстрая и удобная функция, определяющая тип прям из ДНК файла:
private function getSourceMimeType(string $path = ""): bool|string
{
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (is_readable($path)) {
return $finfo->file($path);
}
if (filter_var($path, FILTER_VALIDATE_URL)) {
$fp = @fopen($path, 'rb');
if ($fp) {
$data = fread($fp, 256);
fclose($fp);
return $finfo->buffer($data);
}
}
return false;
}
Какие плюсы:
- используем
finfo, он умеет работать как с локальными файлами, так и с буфером данных;- если нужно узнать тип файла, допустим, по HTTP, то достаточно скачать первые 256 байт для корректного определения MIME;
Мораль: как учит нас практика - верить нельзя никому. Даже
Content-Type. Мне - можно!Будьте бдительны, друзья, и враг не пройдёт!
P.S.: пока писал заметку нашёл ещё хороший вариант, но подходит только для изображений:
$size = getimagesize($url);
echo $size['mime'];
Нюансы:
- работает с URL;
- читает только начало файла;
- сразу возвращает MIME изображения;
#эксперименты #backend #web #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
1 апреля близко-близко
И сердце бьётся как олень
Не подведи меня... а, это про другой день же!
Что ж, весна приносит не только слякоть и долгожданное солнышко, но и некоторые сетевые проблемы, коих в ближайшей перспективе, может только прибавиться.
Поэтому - на всякий случай - оставляю, альтернативные точки связи:
- сделал cообщество https://vk.ru/ordo_code;
- и там же канал https://vk.ru/im/channels/-236655784;
Как этим всем управлять и что там вообще можно делать - я пока представляю смутно.
Для меня ВК всегда был чем-то непонятным, и, честно говоря, таким он и остался. Но реалии требуют адаптироваться - попробую с ним как-то подружиться.
Тут всё довольно привычно и максимально тележно.
У адептов социального эксгибиционизма, может случится приступ переживания за приватность, но мне переживать не за что.
В общем, присоединяйтесь!
Будем на связи, в это непростое сепаратное время.
#на_связи
Please open Telegram to view this post
VIEW IN TELEGRAM
👀1
Даже в Laravel не обойтись без политики
— Как проверить права доступа к модели через Policy —
Сегодня хочу поговорить о политике.
Чего я хуже остальных, что ли...✊
TL;DR
Возникла задача добавить проверку при удаления файла - разрешить пользователю удалять только свои собственные файлы.
Самый простой и правильный способ сделать это в Laravel - использовать Policy.
Policy - специальные классы в Laravel, позволяющие определить логику авторизации для конкретной модели или ресурса.
Преимущества подхода с политиками:
Централизация логики доступа
Поведение задаётся в одном месте - в классе политики
Переиспользование
Policy можно использовать в разных частях приложения
В контроллере:
В шаблонах:
В маршрутах:
Улучшение читаемости
более очевидно считывается, чем
Масштабируемость
Логика доступа со временем может усложняться (роли, админы, shared-ресурсы и т.д.), но благодаря централизованному описанию политики изменения вносятся в одном месте.
Расширяемость
Можно добавлять собственные методы политик, а не ограничиваться только стандартными.
Тестируемость
Отдельный метод политики легко покрывается тестами.
Чёткое разделение ответственности
—
—
—
Policy обнаруживаются автоматически в проекте, если структура проекта стандартная:
Laravel автоматически сопоставит:
Никакой регистрации не требуется.
(Но при необходимости политику можно зарегистрировать вручную в
—————
Политики создаются командой:
А дальше происходит магия соглашения именования и политика применяется к модели.✨
Для своего случая я выбрал вариант проверки доступности на уровне обработки маршрута:
В итоге получается аккуратное, архитектурно правильное и читаемое решение.
Если файл принадлежит пользователю - удаляем, а нет - извините, политика. 📄
#laravel #policy #authorize #backend #web #разработка
— Как проверить права доступа к модели через Policy —
Сегодня хочу поговорить о политике.
Чего я хуже остальных, что ли...
TL;DR
Проверку доступа к модели удобно выносить в Policy и подключать в карте маршрутов.
Возникла задача добавить проверку при удаления файла - разрешить пользователю удалять только свои собственные файлы.
Самый простой и правильный способ сделать это в Laravel - использовать Policy.
Policy - специальные классы в Laravel, позволяющие определить логику авторизации для конкретной модели или ресурса.
Преимущества подхода с политиками:
Централизация логики доступа
Поведение задаётся в одном месте - в классе политики
public function delete(User $user, Attachment $attachment)
{
return $attachment->user_id === $user->id;
}
Переиспользование
Policy можно использовать в разных частях приложения
В контроллере:
$this->authorize('delete', $attachment);В шаблонах:
@can('delete', $attachment)
<button>Delete</button>
@endcanВ маршрутах:
->can('delete', 'attachment')Улучшение читаемости
$this->authorize('delete', $attachment);более очевидно считывается, чем
if ($attachment->user_id !== auth()->id())
Масштабируемость
Логика доступа со временем может усложняться (роли, админы, shared-ресурсы и т.д.), но благодаря централизованному описанию политики изменения вносятся в одном месте.
Расширяемость
Можно добавлять собственные методы политик, а не ограничиваться только стандартными.
Тестируемость
Отдельный метод политики легко покрывается тестами.
Чёткое разделение ответственности
—
Controller - обрабатывает запрос;—
Policy - определяет доступ;—
Model - определяет данные;Policy обнаруживаются автоматически в проекте, если структура проекта стандартная:
app/
├─ Models/
│ └─ Attachment.php
└─ Policies/
└─ AttachmentPolicy.php
Laravel автоматически сопоставит:
Attachment → AttachmentPolicy
Никакой регистрации не требуется.
(Но при необходимости политику можно зарегистрировать вручную в
AppServiceProvider.)—————
Политики создаются командой:
php artisan make:policy AttachmentPolicy --model=Attachment
А дальше происходит магия соглашения именования и политика применяется к модели.
Для своего случая я выбрал вариант проверки доступности на уровне обработки маршрута:
Route::post('/upload/{attachment}/delete', [UploadController::class, 'delete'])
->can('delete', 'attachment')
->name('upload.remove');В итоге получается аккуратное, архитектурно правильное и читаемое решение.
Если файл принадлежит пользователю - удаляем, а нет - извините, политика. 📄
#laravel #policy #authorize #backend #web #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1
Читальня. Питер В. Бретт – Дневная битва
— Такова инэвера —
Продолжаем погружаться в мир Тесы и противостояние людей идемонов людей в третьей книге.
Историяпродолжается начинается заново, но теперь с детства Инэверы - лет за 30 до основных событий, когда могущественная Дамаджах была девочкой и помогала матери плести корзинки.
Если в Копье пустыни нам рассказывали о ханну паш мальчиков, то теперь нам показывают путь девочек - от босячек до загадочных и всемогущих дама'тинг - это если повезёт. Как оказалось, нравы в женских казармах ничуть не мягче чем в мужских - та же жестокость и вечная борьба за место под солнцем.
В остальном, перед нами большое количество политики: придворные игры, интриги, манипуляции и борьба за власть. Красийцы, в лице Джардира, строят планы позавоеванию объединению всё ещё разрозненных поселений северян. 👑
И тут неожиданно интересен Аббан - хаффит, торгаш и поедатель свинины - вообще, на мой взгляд, один из самых любопытных персонажей книги. Пока все вокруг спасают мир, ведут священные войны и исполняют пророчества, Аббан просто делает бизнес.
Герои прокачивают свои магические навыки: Ренна, Арлен, Рожер и даже Лиша, со своим почти научным подходом к делу магии - у всех появляются новые перки. Люди активно совершенствуют оружие и доспехи, покрывая всё - от кончиков пальцев до острия копья - защитными и атакующими метками. Все готовятся к очередному пришествию демонической орды.
Рожер, кстати, прокачался не только в магии: он взял лучшее из красийских традиций - окружил себя двойной красотой. Причём, если с демонами он справляется довольно уверенно, то в домашней дипломатии всё заметно сложнее и запутанее.🚹
Да, совсем уж про демонов автор не забывает. Битва с демонами будет - и демонов на новолуние завезут в изрядных количествах. Они даже будут совершить разные непотребства с главными героями. И в какой-то момент мечта Джардира - объединить людей в битве против демонов - на какое-то время сбудется.
Итого: хорошее продолжение истории. На мой взгляд, немного слабее предыдущих книг, но в целом планку держит на высоте.
Хотя, если честно, создаётся ощущение, что без этой части история в глобальном смысле не слишком много бы потеряла.
7 хора из 10🎲
#книги #почитать #ПитерВБретт #Бретт #ВселеннаяМеченого #ДневняБитва #тёмное #фентези #магия #монстры
— Обзор первой книги - Меченый
— Обзор второй книги - Копьё пустыни
— Обзор четвёртой книги - Трон Черепов
— Такова инэвера —
Продолжаем погружаться в мир Тесы и противостояние людей и
История
Если в Копье пустыни нам рассказывали о ханну паш мальчиков, то теперь нам показывают путь девочек - от босячек до загадочных и всемогущих дама'тинг - это если повезёт. Как оказалось, нравы в женских казармах ничуть не мягче чем в мужских - та же жестокость и вечная борьба за место под солнцем.
В остальном, перед нами большое количество политики: придворные игры, интриги, манипуляции и борьба за власть. Красийцы, в лице Джардира, строят планы по
И тут неожиданно интересен Аббан - хаффит, торгаш и поедатель свинины - вообще, на мой взгляд, один из самых любопытных персонажей книги. Пока все вокруг спасают мир, ведут священные войны и исполняют пророчества, Аббан просто делает бизнес.
Герои прокачивают свои магические навыки: Ренна, Арлен, Рожер и даже Лиша, со своим почти научным подходом к делу магии - у всех появляются новые перки. Люди активно совершенствуют оружие и доспехи, покрывая всё - от кончиков пальцев до острия копья - защитными и атакующими метками. Все готовятся к очередному пришествию демонической орды.
Рожер, кстати, прокачался не только в магии: он взял лучшее из красийских традиций - окружил себя двойной красотой. Причём, если с демонами он справляется довольно уверенно, то в домашней дипломатии всё заметно сложнее и запутанее.
Да, совсем уж про демонов автор не забывает. Битва с демонами будет - и демонов на новолуние завезут в изрядных количествах. Они даже будут совершить разные непотребства с главными героями. И в какой-то момент мечта Джардира - объединить людей в битве против демонов - на какое-то время сбудется.
Итого: хорошее продолжение истории. На мой взгляд, немного слабее предыдущих книг, но в целом планку держит на высоте.
Хотя, если честно, создаётся ощущение, что без этой части история в глобальном смысле не слишком много бы потеряла.
7 хора из 10
#книги #почитать #ПитерВБретт #Бретт #ВселеннаяМеченого #ДневняБитва #тёмное #фентези #магия #монстры
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Не каналами едиными
- Динамическое логирование через Monolog без config/logging.php -
Что ж, поговорим о логировании.
TL;DR
Laravel под капотом имеет удобную систему логирования на основе библиотеки Monolog и каналов логирования. В большинстве случаев этого более чем достаточно, но бывают и исключения, когда каналы начинают мешать.
Мне необходимо было генерировать собственные логи под определённую рутину.✍️
Что за рутина? Микросервис по рассылке автоматических push-уведомлений.
Микросервис на основе генераторов формирует и отправляет пользователям push-уведомления. При этом необходимо логировать процесс генерации: логика довольно ветвистая, сценариев много, а потому нужен глаз да глаз.
Загвоздка заключалась в том, что генераторы создаются автоматически через UI, а поэтому заранее предугадать список каналов логирования невозможно - а логировать надо. Можно было бы всё писать в один файл... да поди потом разберись в мегабайтах текста что там вообще происходит.😰
Не долго кручинясь и не сильно вешая буйну голову, накидал небольшой сервис логирования, который работает без заранее прописанных каналов:💡
RotatingFileHandler автоматически создаёт ежедневные файлы логов:
Ну а дальше всё просто:
В итоге каждый генератор может писать в свой собственный лог, не требуя объявления каналов в config/logging.php.
Иногда лучший способ использовать Laravel - это перестать использовать Laravel.😏
#laravel #logging #monolog #backend #web #разработка
- Динамическое логирование через Monolog без config/logging.php -
Что ж, поговорим о логировании.
TL;DR
Если каналы Laravel не подходят - используем Monolog напрямую. RotatingFileHandler, маленький сервис - и каждый генератор пишет в свой лог.
Laravel под капотом имеет удобную систему логирования на основе библиотеки Monolog и каналов логирования. В большинстве случаев этого более чем достаточно, но бывают и исключения, когда каналы начинают мешать.
Мне необходимо было генерировать собственные логи под определённую рутину.
Что за рутина? Микросервис по рассылке автоматических push-уведомлений.
Микросервис на основе генераторов формирует и отправляет пользователям push-уведомления. При этом необходимо логировать процесс генерации: логика довольно ветвистая, сценариев много, а потому нужен глаз да глаз.
Загвоздка заключалась в том, что генераторы создаются автоматически через UI, а поэтому заранее предугадать список каналов логирования невозможно - а логировать надо. Можно было бы всё писать в один файл... да поди потом разберись в мегабайтах текста что там вообще происходит.
Не долго кручинясь и не сильно вешая буйну голову, накидал небольшой сервис логирования, который работает без заранее прописанных каналов:
class LoggerService
{
protected Logger $logger;
public function __construct(string $filename = 'custom.log')
{
$this->logger = new Logger('custom');
$this->logger->pushHandler(
new RotatingFileHandler(
storage_path('logs/' . $filename),
14,
Logger::DEBUG
)
);
}
....
}
RotatingFileHandler автоматически создаёт ежедневные файлы логов:
storage/logs/push-generator-1-2026-04-07.log
storage/logs/push-generator-1-2026-04-08.log
Ну а дальше всё просто:
$logger = new LoggerService('push-generator-1.log');
$logger->info('Начало генерации');
$logger->warning('Устройство пропущено', ['device_id' => 42]);
$logger->error('Ошибка отправки', ['token' => $token]);В итоге каждый генератор может писать в свой собственный лог, не требуя объявления каналов в config/logging.php.
Иногда лучший способ использовать Laravel - это перестать использовать Laravel.
#laravel #logging #monolog #backend #web #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Как я перестал бояться SQL... и создал полезного монстра
— Как один SQL заменил пачку запросов и килограммы PHP —
Ох, маркетинг, такой маркетинг!
TL;DR
Есть задача: вернуть пользователя к просмотру сериала, который он недосмотрел, и отправить ему push с призывом продолжить.🍿
Изи-пизи... если бы не ряд условий:
- надо найти пользователей, которые смотрели хоть что-то;
- при этом отсеять тех, кто уже досмотрел сериал;
- выбрать “приоритетный” сериал:
— сначала по дате последнего просмотра;
— если одинаково - по количеству просмотренных эпизодов;
Решая задачу «в лоб», на горизонте замаячило большое количество запросов к БД, обработка данных на стороне бэкенда, забитая память и прочие радости. В общем, в перспективе запахло это всё не очень, и я начал терять волю.🤨
А ещё это ломало мою выстроенную парадигму:
Так как требовало дополнительной реализации обработчика, а я человек ленивый.🙄
Вспомнив своё банковское прошлое (ммм, какие там делали причудливые запросы к БД) решил попробовать утащить всю логику в SQL.
В итоге решение можно представить в виде такой схемы:💡
Не совсем тривиальный SELECT, да?😄
Весь SQL приводить не буду - он разросся строк до ~70 и слегка пугает неподготовленного зрителя, но, в целом, картина примерно такая:
Да, выглядит немного монструозно, но результат - просто конфетка.❤️
Что тут интересного:
- использую цепочку CTE (Common Table Expression) через WITH для подготовки данных;
- считаю просмотры и отдельно количество эпизодов;
- отсекаю полностью просмотренные сериалы прямо в БД;
- ранжирую сериалы внутри каждого пользователя через оконные функции (ROW_NUMBER);
- собираю результат в JSON (JSON_OBJECT), чтобы не городить DTO на бэкенде;
⚠️ Но WITH не всегда бесплатно. Иногда MySQL может материализовать CTE и положить данные физически на диск, поэтому в тяжёлых запросах не забываем про EXPLAIN.
It's alive! It's alive!
#sql #cte #with #backend #разработка
— Как один SQL заменил пачку запросов и килограммы PHP —
Ох, маркетинг, такой маркетинг!
TL;DR
Собрал сегмент “недосмотренных сериалов” одним SQL-запросом через WITH + оконные функции. Убрал N+1, сократил нагрузку на бэкенд и получил готовые данные под пуши прямо из БД.
Есть задача: вернуть пользователя к просмотру сериала, который он недосмотрел, и отправить ему push с призывом продолжить.
Изи-пизи... если бы не ряд условий:
- надо найти пользователей, которые смотрели хоть что-то;
- при этом отсеять тех, кто уже досмотрел сериал;
- выбрать “приоритетный” сериал:
— сначала по дате последнего просмотра;
— если одинаково - по количеству просмотренных эпизодов;
Решая задачу «в лоб», на горизонте замаячило большое количество запросов к БД, обработка данных на стороне бэкенда, забитая память и прочие радости. В общем, в перспективе запахло это всё не очень, и я начал терять волю.
А ещё это ломало мою выстроенную парадигму:
запрос к БД -> получение данных -> подготовка данных -> отправка сообщения. Так как требовало дополнительной реализации обработчика, а я человек ленивый.
Вспомнив своё банковское прошлое (ммм, какие там делали причудливые запросы к БД) решил попробовать утащить всю логику в SQL.
В итоге решение можно представить в виде такой схемы:
view_histories (история просмотров)
↓
series_stats (агрегация)
↓
episodes_total (общее число эпизодов)
↓
filtered_series (отсекаем досмотренные)
↓
ranked_series (ранжирование)
↓
финальный SELECT
Не совсем тривиальный SELECT, да?
Весь SQL приводить не буду - он разросся строк до ~70 и слегка пугает неподготовленного зрителя, но, в целом, картина примерно такая:
WITH series_stats AS (
...
),
episodes_total AS (
...
),
filtered_series AS (
SELECT
ss.*,
et.total_episodes
FROM series_stats ss
INNER JOIN episodes_total AS et
ON et.content_id = ss.content_id
WHERE ss.watched_episodes < et.total_episodes
),
ranked_series AS (
SELECT
fs.*,
ROW_NUMBER() OVER (
PARTITION BY fs.app_user_id
ORDER BY fs.last_viewed_at DESC, fs.watched_episodes DESC, fs.content_id DESC
) AS rn
FROM filtered_series AS fs
)
SELECT DISTINCT
...
JSON_OBJECT(
'content_id', rs.content_id,
'watched_episodes', rs.watched_episodes,
'total_episodes', rs.total_episodes,
'last_viewed_at', rs.last_viewed_at
) AS params
FROM app_users AS au
...
INNER JOIN ranked_series rs
ON rs.app_user_id = au.id
AND rs.rn = 1
...
Да, выглядит немного монструозно, но результат - просто конфетка.
Что тут интересного:
- использую цепочку CTE (Common Table Expression) через WITH для подготовки данных;
- считаю просмотры и отдельно количество эпизодов;
- отсекаю полностью просмотренные сериалы прямо в БД;
- ранжирую сериалы внутри каждого пользователя через оконные функции (ROW_NUMBER);
- собираю результат в JSON (JSON_OBJECT), чтобы не городить DTO на бэкенде;
It's alive! It's alive!
#sql #cte #with #backend #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Читальня. Д. Кюнскен – Квантовый сад
— "Срань Господня!" - крикнул Стилс. - "Он антиматерией стреляет!" —
На манеже всё те же — Белизариус Архона снова тащит нас в квантовую шизофрению. Перед нами прямое продолжение немного неоднозначного, но всё-таки весьма интересного «Квантового волшебника».
Мы оказываемся ровно там, где закончилась история первой части: Белизариус всех объегорил, умыкнул врата времени у Суб-Сахарского Союза и нашёл свою асисяй. И тут бы жить-поживать, да добра наживать, но суровая жопа реальности находит нашего героя в виде Конгрегации.
Тут Белизариус рефлексирует.
Конгрегация задумывается о возможностях Homo quantus и в итоге начинают видеть угрозу в квантовых людях. Дабы пресечь угрозу на корню - решают проблему основательно и геноцидят весь родной род Архоны.
Тут Белизариус снова рефлексирует.
Основные действия книги происходят 39 лет назад - да, ребята воспользовались вратами времени, и полетели в прошлое, в те времена, когда Суб-Сахарский Союз был молодым и неокрепшим. Члены экспедиции спали в плохо отапливаемых казармах, над головой висел коричневый карлик, обещая вот-вот погаснуть, а сама экспедиция погрязла в политических интригах и расприях.
На этом фоне появляются двое из ларца: Белизариус и Иеканджика - их задача не наломать дров в прошлом, дабы будущее осталось нетронутым. Решая задачу временных парадоксов, герои оказываются втянутыми в шпионские страсти, с весьма драматичным финалом.
В казармах Белизариус тоже рефлексирует.
Но самое интересное, что герои находят необычную квантовую форму жизни - растения, чей жизненный цикл основан на принципах квантовой суперпозиции. У неё даже есть свой язык, основанный на запахах, и учёные суб-сахарского союза создали девайс-переводчик для общения с ними. Но в итоге судьбу Hortus quantus решает интерпретация фон Неймана — Вигнера (даже пришлось подсмотреть что это такое).💡
Над растениями пуще прежнего рефлексирует Белизариус.
Ещё я бы отметил один момент - это преобразование в Пугало - универсального солдата Конгрегации. И хотя всю книгу сей персонаж сидит в замкнутом пространстве и, в целом не сильно отсвечивает, но история его становления и преобразования кажется неплохой разбавкой общему тону книги. Да и вообще, развить бы историю персонажа - отличный был бы антогонист.
И тут... Ха! Нет! Тут Белизариус не рефлексирует!😄
Итого: книга ощутимо слабее Квантового волшебника - душевных переживаний слишком много, описаний 22-х мерного пространства хватило ещё в первой книге, а сюжет какой-то невзрачный по итогу. И знаете... возглас Стилса очень хорошо описывает послевкусие от книги. Не-не, я не про антиматерию ;)
Но при всём при этом, если у нас издадут продолжение, я скорее всего его почитаю💅 (говорят там подинамичнее происходящее) - вселенная же ж интересная, а геномодифицированные люди до конца себя ещё не показали.
5 пугало из 10
#книги #почитать #ДерекКюнскен #Кюнскен #КвантоваяЭволюция #КвантовыйСад #хроно #фантастика #космос
— Обзор первой книги - Квантовый волшебник
— "Срань Господня!" - крикнул Стилс. - "Он антиматерией стреляет!" —
На манеже всё те же — Белизариус Архона снова тащит нас в квантовую шизофрению. Перед нами прямое продолжение немного неоднозначного, но всё-таки весьма интересного «Квантового волшебника».
Мы оказываемся ровно там, где закончилась история первой части: Белизариус всех объегорил, умыкнул врата времени у Суб-Сахарского Союза и нашёл свою асисяй. И тут бы жить-поживать, да добра наживать, но суровая жопа реальности находит нашего героя в виде Конгрегации.
Тут Белизариус рефлексирует.
Конгрегация задумывается о возможностях Homo quantus и в итоге начинают видеть угрозу в квантовых людях. Дабы пресечь угрозу на корню - решают проблему основательно и геноцидят весь родной род Архоны.
Тут Белизариус снова рефлексирует.
Основные действия книги происходят 39 лет назад - да, ребята воспользовались вратами времени, и полетели в прошлое, в те времена, когда Суб-Сахарский Союз был молодым и неокрепшим. Члены экспедиции спали в плохо отапливаемых казармах, над головой висел коричневый карлик, обещая вот-вот погаснуть, а сама экспедиция погрязла в политических интригах и расприях.
На этом фоне появляются двое из ларца: Белизариус и Иеканджика - их задача не наломать дров в прошлом, дабы будущее осталось нетронутым. Решая задачу временных парадоксов, герои оказываются втянутыми в шпионские страсти, с весьма драматичным финалом.
В казармах Белизариус тоже рефлексирует.
Но самое интересное, что герои находят необычную квантовую форму жизни - растения, чей жизненный цикл основан на принципах квантовой суперпозиции. У неё даже есть свой язык, основанный на запахах, и учёные суб-сахарского союза создали девайс-переводчик для общения с ними. Но в итоге судьбу Hortus quantus решает интерпретация фон Неймана — Вигнера (даже пришлось подсмотреть что это такое).
Над растениями пуще прежнего рефлексирует Белизариус.
Ещё я бы отметил один момент - это преобразование в Пугало - универсального солдата Конгрегации. И хотя всю книгу сей персонаж сидит в замкнутом пространстве и, в целом не сильно отсвечивает, но история его становления и преобразования кажется неплохой разбавкой общему тону книги. Да и вообще, развить бы историю персонажа - отличный был бы антогонист.
И тут... Ха! Нет! Тут Белизариус не рефлексирует!
Итого: книга ощутимо слабее Квантового волшебника - душевных переживаний слишком много, описаний 22-х мерного пространства хватило ещё в первой книге, а сюжет какой-то невзрачный по итогу. И знаете... возглас Стилса очень хорошо описывает послевкусие от книги. Не-не, я не про антиматерию ;)
Но при всём при этом, если у нас издадут продолжение, я скорее всего его почитаю
5 пугало из 10
#книги #почитать #ДерекКюнскен #Кюнскен #КвантоваяЭволюция #КвантовыйСад #хроно #фантастика #космос
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Призраки в сети — тайна пропадающего домена
— О чём молчат минималистичные Docker-образы —
TL;DR
Интересный кейс случился на днях. В логах приложения стали сыпаться сообщения:
🤌
Первым делом проверил что там видит
Оказалось - нифига он не видит.
Проверил что видит сам хост:
Видит! Видит таймаут.🤦♂️
Пропинговал DNS-сервер, которые выдал провайдер - не пингуется.
На всякий случай проверил резолв на общеизвестных DNS-серверах:
И получил вполне бодрый ответ - домен резолвится отлично.
Сделав единственно логичный вывод, - проблема на стороне хостера с DNS-сервером - приступил к лечению:
— отредачил
— обновил DNS на интерфейсе
— прописал адреса DNS для docker пожёстче:
Отписал в поддержку о проблеме и пошёл пить кофе, и жевать конфеты!☕️
В безмятежном состоянии пребывал не долго - повальная ошибка😭
Картина получалась интересная: на хосте домен резолвился без каких-либо замечаний, а вот из докера домен периодически не резолвился - то есть DNS то жив, то мёртв, то притворяется.
И вот тут я реально приуныл, потому что никаких явных причин для такого поведения просто не было.
Пробовалось многое:
— перевод запросов к DNS на tcp;
— разумеется, несколько ребутов;
— пересоздание сетей
— молитвы Омниссии🤖 ;
В общем, весь опыт накопленный человечеством оказался бесполезен.😡
Дабы долго не томить - проблема оказалась в образе -
Известные проблемы
— упрощённый DNS‑клиент.
— ограниченная обработка ошибок. При проблемах с первым DNS‑сервером
— особенности кэширования. Поведение кэша DNS в
— сетевые взаимодействия. В Docker‑сетях (особенно overlay)
— таймауты.
❗️ Мораль❗️
Ну, а
Моё сердце разбито!😭
#docker #php #laravel #alpine #musl #devops #backend #web #разработка
— О чём молчат минималистичные Docker-образы —
TL;DR
Если Docker-контейнер на php:*-alpine периодически ловит cURL error 6: Could not resolve host, - проблема может быть в musl, а не в Docker или DNS.
Интересный кейс случился на днях. В логах приложения стали сыпаться сообщения:
cURL error 6: Could not resolve host: here-some-secret-domain.com
Первым делом проверил что там видит
docker у себя внутрях при резолве домена:docker compose exec php getent hosts here-some-secret-domain.com
Оказалось - нифига он не видит.
Проверил что видит сам хост:
dig here-some-secret-domain.com
;; communications error to 172.16.2.231#53: timed out
Видит! Видит таймаут.
Пропинговал DNS-сервер, которые выдал провайдер - не пингуется.
На всякий случай проверил резолв на общеизвестных DNS-серверах:
dig @8.8.8.8 here-some-secret-domain.com
; <<>> DiG 9.10.6 <<>> @8.8.8.8 here-some-secret-domain.com
; (1 server found)
И получил вполне бодрый ответ - домен резолвится отлично.
Сделав единственно логичный вывод, - проблема на стороне хостера с DNS-сервером - приступил к лечению:
— отредачил
/etc/resolv.conf, указав, что используем 8.8.8.8 и 4.4.4.4;— обновил DNS на интерфейсе
resolvectl dns eth0 4.4.4.4 8.8.8.8;— прописал адреса DNS для docker пожёстче:
services:
php:
dns:
- 8.8.8.8
- 4.4.4.4
Отписал в поддержку о проблеме и пошёл пить кофе, и жевать конфеты!
В безмятежном состоянии пребывал не долго - повальная ошибка
cURL error 6: Could not resolve host ушла, но периодически нет-нет, да и появится. И это было весьма болезнено. Картина получалась интересная: на хосте домен резолвился без каких-либо замечаний, а вот из докера домен периодически не резолвился - то есть DNS то жив, то мёртв, то притворяется.
И вот тут я реально приуныл, потому что никаких явных причин для такого поведения просто не было.
Пробовалось многое:
— перевод запросов к DNS на tcp;
— разумеется, несколько ребутов;
— пересоздание сетей
docker;— молитвы Омниссии
В общем, весь опыт накопленный человечеством оказался бесполезен.
Дабы долго не томить - проблема оказалась в образе -
php:8.4-fpm-alpine. Alpine использует musl вместо glibc, и у musl исторически бывают очень нестабильные отношения с DNS, Docker networking и резолверами.Известные проблемы
musl с DNS:— упрощённый DNS‑клиент.
musl не реализует все механизмы glibc, например, сложные стратегии ретраев и таймаутов;— ограниченная обработка ошибок. При проблемах с первым DNS‑сервером
musl может не переключиться на следующий в списке;— особенности кэширования. Поведение кэша DNS в
musl отличается от glibc - возможны устаревшие ответы или пропуски обновлений;— сетевые взаимодействия. В Docker‑сетях (особенно overlay)
musl иногда некорректно обрабатывает ответы от встроенного DNS‑сервера Docker (127.0.0.11).— таймауты.
musl имеет жёсткие таймауты по умолчанию, что критично при задержках в сети;Не гонись, поп, за дешевизной -
Малый образ - геморрой длиной в полжизни!
Ну, а
alpine теперь буду использовать только для локальной разработки, а ведь образы так нравились своей минималистичностью. Моё сердце разбито!
#docker #php #laravel #alpine #musl #devops #backend #web #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Хирургическая очистка кэша в Yii2
— Не все зависимости одинаково вредны —
TL;DR
Что ж друзья, сегодня поговорим о зависимостях. Все знают, что это такое. Сначала кажется, что всё под контролем. Потом они начинают влиять на твою жизнь. А потом ты уже не представляешь, как жил без них.😍
Зависимости бывают у всех. У людей, у проектов, у
Кароч! Рассказываю...
Делал я одну фичу. Суть её сейчас не важна, но появилась необходимость складывать данные, получаемые в ходе работы, в кэш. Ну надо так надо - складываем. А что делают с кэшированными данными? Правильно — периодически чистят для поддержания гигиены и актуальности. И вот тут нашла коса на камень.
Ключи кэша в данной фиче составные и зависят от ряда параметров. Ключи примерно такие —😫
И как это всё очищать спросите вы. Ведь спросите же?
Вариантов решения вроде бы хватает. Можно хранить список ключей отдельно, можно искать по префиксам, можно генерировать какие-нибудь служебные ключи для очистки, но всё это выглядит как костыли. Не, можно ещё беспощадно сделать —
Другое дело — зависимости кэша.💡
Для своей задачи я использовал:
Синтаксис максимально простой и понятный:
А инвалидация кэша делается ещё проще:
Разумеется, работает это только с кэш-бэкендами, которые поддерживают зависимости, но для типичных Redis, Memcached и файлового кэша проблем обычно не возникает.
И всё — никаких тебе поисков по префиксам, генерации ключей и прочего мракобесия.
Просто, изящно, профессионально!☕️
#php #yii2 #cache #dependency #backend #web #разработка
— Не все зависимости одинаково вредны —
TL;DR
Волшебный TagDependency позволяет привязать к одному тегу сколько угодно записей кэша и потом инвалидировать их одной командой.
Что ж друзья, сегодня поговорим о зависимостях. Все знают, что это такое. Сначала кажется, что всё под контролем. Потом они начинают влиять на твою жизнь. А потом ты уже не представляешь, как жил без них.
Зависимости бывают у всех. У людей, у проектов, у
npm-пакетов... и даже у кэша в Yii2. И штука эта, надо сказать, офигенная, хотя пользуются ей незаслуженно редко. За всю свою практику я ни разу не встречал её на реальных проектах. Обычно же как: ключ, данные, TTL — и погнали дальше.Кароч! Рассказываю...
Делал я одну фичу. Суть её сейчас не важна, но появилась необходимость складывать данные, получаемые в ходе работы, в кэш. Ну надо так надо - складываем. А что делают с кэшированными данными? Правильно — периодически чистят для поддержания гигиены и актуальности. И вот тут нашла коса на камень.
Ключи кэша в данной фиче составные и зависят от ряда параметров. Ключи примерно такие —
cache.for.feature.key1.key2.key3. И их конечное количество неизвестно. Ну как неизвестно... Примерно дохреналиард их. И как это всё очищать спросите вы. Ведь спросите же?
Вариантов решения вроде бы хватает. Можно хранить список ключей отдельно, можно искать по префиксам, можно генерировать какие-нибудь служебные ключи для очистки, но всё это выглядит как костыли. Не, можно ещё беспощадно сделать —
Yii::$app->cache->flush(). Очищай больше, хрен ли его жалеть! Другое дело — зависимости кэша.
Для своей задачи я использовал:
TagDependency — cвязывает кэшированные данные элемента с одним или несколькими тегами и позволяет инвалидировать данные кэша по этому тэгу.Синтаксис максимально простой и понятный:
Yii::$app->cache->set(
$cacheKey,
$cacheData,
$cacheTtl,
new TagDependency(['tags' => $tag])
);
А инвалидация кэша делается ещё проще:
TagDependency::invalidate(
Yii::$app->cache,
$tag
);
Разумеется, работает это только с кэш-бэкендами, которые поддерживают зависимости, но для типичных Redis, Memcached и файлового кэша проблем обычно не возникает.
И всё — никаких тебе поисков по префиксам, генерации ключей и прочего мракобесия.
Просто, изящно, профессионально!
#php #yii2 #cache #dependency #backend #web #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1