PICO – Telegram
PICO
104 subscribers
46 photos
1 video
39 links
Логово киберайтишника
IT / FP / OOP / DevOps / .NET / SQL
@picolino
Download Telegram
Недавно удалось потрогать прекраснейший инструмент для хранения в кодовой базе визуализации графовых структур - ascii диаграммы

Без шуток, если у вас в проекте есть графы и вы испытываете необходимость в документировании различных сценариев/представлений графов - этот подход максимально удобен.

Обычно документация к сложной логике, построенной на графах, располагается где-то вне кодовой базы, а в самом коде ссылок на эту документацию, как правило, не найти, вот и сидишь, ковыряешь, пытаешься разобраться.

Использование инструментария для рисования ASII диаграмм - это полноценный Docs-as-Code, который прост в генерации и лёгок в поддержке, а самое главное - читабелен для других коллег-разработчиков. Его можно использовать, например, для UML-диаграмм сложной ветвистой логики, или изображения диаграмм взаимодействия различных компонентов.

Я использовал этот подход для документирования unit-тестов, где рисовал то, как устроен граф, над каждым тестовым сценарием. Получилась годно.

Полезные ссылки: ASCIIFlow

#tools

👾 PICO
👍1💩1
🔥ATDD🔥

Я стартую уже второй проект с использованием этого подхода и не могу нарадоваться, как легко становится вносить в код изменения и не бояться за фатальные баги.

Сам подход состоит из нескольких шагов:

1. Описываем логику приложения на русском языке (с использованием нотации gherkin), наполняя пользовательские сценарии. Это происходит в отдельных .feature-файлах в директориях для тестов.

2. На каждый шаг сценария делаем его репрезентацию в коде. То есть говорим приложению, как транслировать русский текст сценария в конкретный набор исполняемого кода

3. Запускаем тест. Profit

Конечно, есть свои нюансы, но код, получающийся при проектировании по ATDD получается гораздо качественней, а "встроенная" документация по пользовательским сценариям напрямую из тестов позволит гораздо проще осознать логику приложения новым людям на проекте.

Ну и плюс ко всему - основные пользовательские сценарии автоматически становятся покрыты тестами, что обеспечивает приложению стабильность в рефакторинге и дальнейшим изменениям.

Не пренебрегайте TDD подходами, они реально рулят, когда речь заходит о создании качественного долгоживущего ПО.

Полезные ссылки: SpecFlow для .NET

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
💩1
👊 Битва пет-проектов

Мы вместе с Хабр.Карьерой запускаем уникальное мероприятие - онлайн-битву IT-команд!

💎 Команда Sapphire - полнофункциональная команда с составом 14 человек.

Представители энтерпрайза, полноценного пайплайна разработки с аналитиками и тестировщиками, современным стеком технологий и разделением репозиториев на фронт/бек.

♨️ Команда Garnet - лимитированная с составом 8 человек.

Представители стартапа со специально подобранным стеком для ускоренной разработки, одним репозиторием на фронт и бек, полагающаяся исключительно на автоматизированные тесты

Перед обеими командами стоит одна задача: разработать продукт для командного взаимодействия и ведения проектов.

То как каждая команда подойдёт к этому заданию и что в итоге получится - узнаем совсем скоро!

Нас ждут также:
- Воркшопы по разработке и командные прямые эфиры
- Q&A сессии
- Стендапы и демо

И главная фишка: Все публично! Можно будет в онлайн-режиме следить за внутрикомандным взаимодействием в чатах самих команд и за ходом проектов в командных репозиториях.

От себя надеюсь, что мероприятие окажется в первую очередь полезным, ну, а там поглядим, может быть мы реально годные продукты забацаем :)

Старт уже на следующей неделе!

Ссылки: Лендинг битвы пет-проектов

👾 PICO
🔥2💯1
📦 Kamal Deploy

Как же я долго ждал этого инструмента... и как жаль, что он существует уже несколько месяцев, а я узнал о нем только сейчас.

Перед стартом битвы пет-проектов стояла задача настроить быстрое и безболезненное развертывание веб-приложения на различные окружения. Ну я чето мурыжился, кубер настраивать очень не хочется (да и есть ограничения для него на инфраструктуре), ну, думаю, докер наше все, пошел уже настраивать docker-compose и тут...

Выходит пост у Феди Борщева про Kamal (бывш. mrsk). Ну я прочитал, думаю, прикольная тема, надо попробовать. И какой же это кайфовый инструмент!

Все что нужно на конечной машине - это поднятый docker. А на своей тачке (или внутри какого-нибудь пайплайна сборки) нужно просто поставить докер и утилиту kamal. Все, никаких зависимостей и громоздких инструментов.

Публикация проекта на окружения происходит с помощью трёх команд в первый раз и в одну во все последующие разы:

- kamal init для регистрации проекта и создания конфигов
- kamal setup для первоначального развертывания
- kamal deploy для всех последующих

Kamal просто подключается к нужной тачке, прописанной в конфиге, через ssh и сам собирает (с помощью Dockerfile) и деплоит ваше приложение, в добавок ко всему поднимает над ним reverse-proxy и делает базовый health-check. Он поддерживает откат релизов а также взаимодействует с различными registry для сохранения версий релизов.

Тупа огонь для скоростной настройки деплоя 🔥

Ссылки:
- Официальный сайт инструмента Kamal
- Настройка деплоя сервиса с помощью Kamal

#tools

👾 PICO
👍5💩1
Не нравится? Перепиши!

За последние 2 месяца, так получилось, я начал два проекта с нуля. Один с командой, второй соло. Ну и ещё в третий проект вписался, в существующую команду и с имеющимся кодом.

Как же всё-таки важна программная архитектура. Новые проекты всегда хороши тем, что перед тобой чистый лист. Естественно ты практически сразу измажешь его говном, без вариантов, но до этого момента есть время насладиться реально красивым кодом.

Что делать чтобы этот лист испачкался как можно позже? Естественно, выстраивать ограничения для самого себя. Ставь заборы там, куда идти не стоит, клади асфальт туда, куда будешь ехать. И самое главное - модульность, модульность, модульность!

Понял, что капитально накосячил на старте? Ну и выкинь модуль, перепиши нормально, под переосознанные требования, завтра скажешь себе большущее спасибо, и не только ты, но и люди, которые с тобой работают.

После реализации очередного модуля стараюсь всегда спрашивать себя: а нравится ли мне то, что получилось?

Казалось бы такой банальный вопрос, но именно он иногда заставляет взять и подойти к решению по-новой. Сделать элегантнее и лучше.

👾 PICO
4💩1
🔥4💯1
Автотесты - первый помощник тимлида

Для битвы пет проектов я решил попробовать относительно новый для себя подход - ATDD, о котором я уже рассказывал. И, к удивлению для себя самого, я ни разу об этом не пожалел.

Начну, внезапно, с минусов. Это время. Да, на реализацию фичи через автотесты уходит время. Где-то в каком-то исследовании даже видел конкретную цифру, фича занимает в среднем на 16% больше времени, если разработка идет через тестирование или если на фичу тесты пишутся после реализации. По прошествии полутора недель активной работы, это действительно ощущается так. Возможно, мы тратим на это даже больше.

Но самое интересное, что... больше минусов нет.

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

Наш процесс приемки задач состоит из одного шага - код-ревью. Код решает задачу наших пользователей потому что мы начинаем разработку с пользовательского сценария. А в том что он точно работает я убеждаюсь благодаря автотестам.

Вы только посмотрите на наш Code Coverage (скрин в шапке). Помимо очевидного покрытия кода тестами эти цифры также показывают нам, что мы не делаем лишних вещей. Все о чем говорится в сценарии должно быть покрыто тестами. И оно покрыто.

Благодаря такому подходу я, как лид команды, в рамках ревью фокусируюсь на качестве кода, на его архитектуре, на взаимодействиях между модулями, и совершенно не беру на себя ответственность контролировать качество работы написанного кода, его соответствие требуемой бизнес-логике, так как эти вещи в нашем подходе автоматизированы благодаря ATDD.

Да, мы тратим больше времени на разработку, но мы получаем невероятную экономию буквально всех ресурсов команды на тестировании и контроле качества.

Пушка-бомба, лидам настоятельно рекомендую, особенно на новых проектах 🦀

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5🤡1
Monolith over Microservices

Да-да, я снова про битву пет-проектов. На этот раз поговорим об архитектуре.

В кругу разработчиков часто популярен холивар в отношении программных архитектур для web-сервисов, мол, что выбрать, монолит или микросервисы, а для каких задач что подходит лучше и т.д. Есть строгие приверженцы одного из подходов, есть балансирующие между, но суть споров чаще всего одна - плюсы и минусы которые тот или иной подход в себе несет. Как-то я написал развернутый ответ на SO об отличиях монолитов и микросервисов и как плавно переходить от одного к другому.

Перед стартом битвы пет-проектов я тоже столкнулся с этой дилемой. С одной стороны есть монолит - простое и верное решение с минимальными затратами, но высокими рисками "завязывания" кода. С другой - микросервисы, хайповый и популярный путь с минимумом зависимостей, но сложностью развертывания и взаимодействия между сервисами.

А что если мы постараемся взять плюсы обоих подходов?

Допустим, у нас есть веб-сервис, единый (монолитный) исполняемый файл, под которым прячутся 2-4 микросервиса.

Какие плюсы:
- Простота развертывания. Один докерфайл и больше ничего. В отличие от классических микросервисов.
- Слабая связанность. Микросервисы внутри строго отделены друг от друга. От монолита требуется только запустить их всех вместе.
- Очень быстрый переход на микросервисные рельсы, в случаях, когда это необходимо. Мы просто выносим микросервис из монолита и разворачиваем отдельно по щелчку пальца.

Минусы:
- Нужно очень хорошо продумать архитектуру решения. Так чтобы можно было и быстро микросервис отделить и обеспечивалась достаточная обобщенность настройки.
- Не все внешние библиотеки можно настроить для исполнения под такой архитектурой. Я бы даже сказал, что их достаточно мало.

Можно сказать, что это переизобретенный SOA, но ключевое отличие тут в том, что микросервис - это не модуль ПО, а полноценное приложение со своими точками входа для пользователей.

Пример подобной архитектуры можно посмотреть в нашем репозитории для битвы

👾 PICO
le classique
😁1
Developer Experience

Недавно состоялся вебинар в моей любимой школе сильных программистов на тему так называемого developer experience. Не сказать, что он прошел прям увлекательно, но и не бесполезно 🏃‍♀️

Если кратко, то DevEx - это про удобство разработчика. А суть развития DevEx - это привнесение в свою профессиональную деятельность больше удовольствия (читай: эффективности) и, соответственно, меньше ерунды.

В разработке обычно как, вот есть у тебя кодовая база, сиди работай. Горит дедлайн? Нужно успеть в срок. Огромный техдолг? Терпи, братиш, мы - бизнес, мы рубим деньги. Мы работаем на пределе возможностей, но нужен результат лучше? Просто наймем новых программистов! Или ничего не будем делать, если денег нет :C

Крайне мало кто задумывается о том, а насколько программистам в удовольствие работать в компании? Сравнивать максимализируя лучше всего.

Вот есть программист Паша, работает с легаси кодовой базой, огромным техдолгом и 1-2 встречами в день по часу каждая. Будет ли он доволен? Будет ли эффективен? Да конечно нет, ему захочется скорее закрыть IDE с этим ужасом и пойти домой пилить свои пет-проекты. Повседневная деятельность Паши в тягость

А есть разработчик Юля, работает в репозитории с чистой архитектурой, с автотестами и автодеплоем. Будет ли она довольна? Будет ли эффективна? Ну конечно да! Ведь на выполнение задач уходит в разы меньше времени, а количество багов измеряется единицами. Повседневная деятельность Юли в радость

В DevEx легко разглядеть реально полезный для всех сторон (win-win) мотиватор. Делай своим разработчикам хорошо и получай эффективный результат. В слепой погоне за целями часто можно упустить простейшие инструменты повышения эффективности, этот, на мой взгляд, один из таких. Что-то из серии "нормально делай - нормально будет".

Ну а если вы не управляете людьми - вы можете инвестировать в свой собственный DevEx. Просто спросите себя: А что я могу сделать, чтобы получать больше удовольствия от повседневной разработки?

Возможно, ответ вас удивит 🐸🐸🐸

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
💩2
Каша в репозитории

В недавнем прямом эфире на хабр.карьере я рассказывал про SpecFlow и вскользь упомянул о "каше", которая появляется, если разработчики перестают следить за структурой и жёсткими рамками архитектуры проекта.

Казалось бы, проблема не нова, но до сих пор встречаю репозитории с этой проблемой, где просто нет внятных решений, которые бы направляли и подсказывали мне "а как тут принято".

Отсутствие подобных решений приводит к тому, что новый код, который напишется в рамках работы над репозиторием, будет лишён "направления". И получается, что каждый программист привносит в структуру репозитория свое собственное видение, которое ничем не ограничено, что и влечет за собой появление "каши". Достаточно неприятный фактор, контроль которого ложится на плечи роли, отвечающей за архитектуру решения. Но чаще всего на проблему просто забивают.

Методик избавления от этой каши много, но их все объединяет один принцип - это выстраивание архитектурных ограничений.

В последнее время я применяю для этого несколько подходов:

- Гексагональная архитектура. Стандартный способ разделения приложения на слои. Глубину ее применения можно очень удобно регулировать, например, объединив слои Application и Domain, если доменная область достаточно проста. Это позволяет контролировать гибкость внедряемых архитектурой ограничений.
- Feature Sliced Design (FSD). Суть его в том, что сначала кодовая база разделяется на слои, затем на фичи (слайсы), и лишь только в конце на компоненты (репозитории, команды, хелперы и тд.). Не смотря на то, что подход считается основой для фронтендеров - ничего не мешает применять схожий подход и на бекенде. Его внедрение в конечном итоге очень сильно помогает быстрее искать место необходимости внесения изменений и кратно снижает когнитивную нагрузку.
- SpecFlow и ATDD. Написание нового функционала через автотесты автоматически добавляет ограничение "тестируемости", что хорошо сказывается как на архитектуре, так и на качестве итогового продукта, его готовности к последующим изменениям.

👾 PICO
3
literally me
🔥2
GraphQL + CQRS

Решил наконец ознакомиться с графом и был приятно удивлен его возможностями.

Кто не в теме, очень кратко:

GraphQL - это прямая противоположность REST. Единая точка входа. Принимает набор команд, отдает результат их исполнения. При этом в самом запросе определяются возвращаемые данные.


Представим, что нам необходимо сделать функционал отображения двух списков. Первый - подробный, с названием, картинками, длинным описанием и комментариями. Второй - упрощенный, отображающий только название входящих в него элементов

В REST мы бы подготовили два эндпоинта. Один для получения полного списка, второй для упрощённого. При этом на бекенде необходимо будет для каждого эндпоинта реализовать свой маппинг.

А в графе все очень просто. Мы описываем максимально полную модель подробного списка. А уже на фронтенде определяем где нам нужно выгрузить подробную информацию по списку, а где нужна минимальная, просто передавая на бекенд поля, которые ожидаем получить.

Плюс ко всему, в рамках одного запроса к одному эндпоинту графа мы можем получить сразу несколько сущностей, обращаясь как будто бы к разным эндпоинтам REST'а.

Это даёт огромную гибкость, атомарность в разработке фронтенда и упрощает архитектуру бекенда.

Правда точки зрения скорости не все гладко, на каждый запрос нам приходится так и так доставать из базы максимально полную модель требуемых данных, а затем резать их перед отдачей на фронт. Ну, или придумывать довольно непростые хаки, чтобы оптимизировать чтение.

На GraphQL очень хорошо ложится CQRS паттерн. Поскольку на фронте мы получаем атомарность, можно экстраполировать ее и на наш бекенд. В рамках запроса могут выполниться, например, одновременно несколько queries или commands, отрабатывая по очереди на уровне бекенда.

Таким образом мы получаем четкое разделение ответственности на бекенде, избавляемся от каши в репозитории и соблюдаем единообразие кодовой базы.

Я определенно точно познал не весь дзен использования графа. Продолжаю наблюдение 👀

- GraphQL для C#: HotChocolate

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
😵 CancellationToken через DI

Галя, отмена!


Современный веб сделан так, что на открытие одной странички на сервер летит с десяток запросов за данными. Если юзер быстро навигируется по сайту\приложению - мы можем получить ситуацию, что большая часть запросов ему просто не нужна. А сервер продолжает на эти запросы пахать. Чтобы чуток помочь нашему серверу мы можем реализовать функционал отмены запросов.

В C# (ASP.NET) есть встроенный механизм, который позволяет получить сигнал о том, что пользователь отменил запрос. Из этого механизма мы можем получить CancellationToken, взаимодействуя с которым проверять, ждет ли еще пользователь нашего запроса, или мы можем его отменить?

В общем случае CancellationToken прокидывают в параметрах методов (из-за опасности возникновения captive dependencies - про это расскажу как-нибудь позже). Но если вдруг у вас в приложении все классы, которым нужен токен (в основном репозитории, адаптеры к файловой системе, адаптеры к другим API), регистрируются как Scoped - то вы можете себе позволить заинжектить его через DI и немножко облегчить себе жизнь.

Создаем провайдер токена из контекста запроса:

public class CancellationTokenProvider
{
public CancellationTokenProvider(
IHttpContextAccessor httpContextAccessor
)
{
Token =
httpContextAccessor.HttpContext
?.RequestAborted
?? CancellationToken.None;
}

public CancellationToken Token { get; }
}


Подключаем в DI:
services.AddHttpContextAccessor();
services.AddScoped<CancellationTokenProvider>();

Юзаем:
private readonly CancellationToken _ct;

public Repository(CancellationTokenProvider ctp)
{
_ct = ctp.Token;
}


P.S. Никита, спасибо, что напомнил про эту штуку!

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
👾6🤔1
Excalidraw

Лучший тул для изложения мыслей на экран.

Если вы рисуете схемки, диаграммы или небольшие макеты в каком-нибудь draw.io или visio, то наверняка вы сталкивались с ощущением, что для вашей задачи инструмент выбран черезчур уж громоздкий.

Постоянно жил с этим чувством, всегда хотелось, чтобы "как на бумаге", пока поиск инструмента попроще не привел меня к замечательному продукту excalidraw.

Не буду петь про него дифирамбы - просто посмотрите сами, как там все лаконично и просто. С4 архитектурную диаграмму крупного предприятия, конечно, в нем строить не стоит, но вот для изложения своих мыслей на экран и быстрых "зарисовок" - самое то.

Не пользуюсь планшетами, но по инфе с реддита - отлично работает и на них.

Синхронизация между девайсами доступна только по подписке, но такому инструменту я точно бы забашлял, пользуюсь какой год. В любом случае, о широких возможностях импорта\экспорта разработчики не забыли и в бесплатной версии.

Попробовать можно тут

#tools

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥4👍1👾1
🟥 Positive Technologies - Лидер рейтинга IT-брендов 2023

Не могу не поделиться, очень приятно ощущать в том числе и свой вклад в эту победу!

Команда максимально крутых профессионалов с ультра-интересными задачами и здоровой корпоративной культурой.
Заслуженно!

Но над узнаваемостью нужно еще потрудиться, работаем!

Если интересна тема кибербезопасности - натыкайте лайков, мб расскажу че-нить годное из этой сферы

https://habr.com/ru/specials/773642/

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9💩1
🔥4😁2
Ory

Ахах, ору


Достаточно интересная линейка продуктов для Identity Management - всего, что связано с аутентификацией и авторизацией пользователей.
С этой линейкой можно:

Поорать с греческой мифологии в Ory Kratos

Кратос - это сердце identity системы. Он управляет пользователями и пользовательскими сессиями. Ставите postgres, поднимаете Кратос, прогоняете миграции, вуаля, айдентити система готова, эндпоинты для регистрации, авторизации и вот этого всего можно найти в документации.

Принести клятву верности в Ory Oathkeeper

шКипер - это прокси со встроенной проверкой на доступ к ресурсам. Ставите Кратос, ставите ваш продукт рядом, ставите Кипер над всем этим добром, настраиваете маршрутизацию. Теперь только авторизованные (через Кратос) пользователи могут получить доступ к вашему продукту. Удобно. Также можно поставить его под какой-то из существующих проксей, типа traefik или nginx.

Побороться с древними существами в Ory Hydra

Гидра позволяет подключить авторизацию и аутентификацию по OAuth2 и OIDC к существующей iam системе, чтобы обеспечить бесшовную авторизацию между различными системами и продуктами.

Не знаю, придумайте аналогию сами - Ory Keto

Кето - это про пользовательские роли и привилегии. Он поможет отвечать на вопрос "а может ли этот пользователь обращаться к этому ресурсу?". Гибкая система конфигурации и правил, подробности, опять же, в документации.

Вывод

Открытый исходный код, последние стандарты безопасности, быстрое развертывание в пару команд, поддержка различных веб-хуков и гибкая конфигурация.
В целом продуктами доволен, работают стабильно и достаточно быстро.

Из небольших минусов могу отметить жесткую привязку к postgres в качестве хранилища данных. Поднять продукты Ory, например, на Mongo, не получится.

Также не очень зашла документация, достаточно сложна для восприятия, но при желании и методом "тыка" разобраться можно.

Если нужно готовое решение для полного флоу аутентификации пользователей - заценить линейку точно стоит.

Официальный сайт Ory

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Captive Dependencies

В недавнем посте про Cancellation Token я вскользь упоминал про эту проблему. Пришло время рассказать о ней поподробнее.

Captive Dependency - это ситуация, когда объект с быстрым жизненным циклом является зависимостью для объекта с медленным жизненным циклом. В контексте ASP.NET такая ситуация возникает тогда, когда вы регистрируете класс как Singleton, а в его зависимостях присутствуют классы, зарегистрированные как Scoped.

В отношении CancellationToken ситуация аналогичная. CancellationToken - это токен отмены текущего запроса, он зарегистрирован как Scoped и имеет короткий жизненный цикл. И если мы загружаем CancellationToken в конструктор Singleton-объекта, то вот и получается Captive Dependency. Именно по этой причине самым безопасным путем будет прокидывать CancellationToken параметром метода, потому что вызов метода (даже у singleton-объекта) гарантированно происходит в рамках scope-а.

Конфигурация с имеющимися в ней Captive Dependencies по факту является ошибочной, но различные DI-фреймворки позволяют настраивать отношение к такого рода конфигурациям.

Например, стандартный Microsoft DI имеет встроенный механизм валидации, который за вас пройдется по всему дереву собираемых зависимостей и определит наличие captive dependencies, а затем даст леща выбросит эксепшн с указанием, мол "ай-ай-ай, так делать нельзя", но его нужно не забыть включить при сборке скоупа. Красиво, Майки, спасибо!

А вот популярная библиотека для зависимостей Autofaс прямым текстом говорит:

Stopping captive dependencies is the responsibility of the developer.


Заставляя бедных разработчиков вручную просматривать дерево зависимостей, сформированное autofac и искать проблемные места (самому злейшему врагу не пожелаю столкнуться с этим в большом проекте).

Избегать этой проблемы нужно начиная с самых ранних этапов зарождения проекта, а самый дельный совет при этом стар как сам фортран - избегайте singleton'ов, а если они и необходимы, то делайте их максимально независимыми от других объектов.

👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔3