Media is too big
VIEW IN TELEGRAM
PlanetScale now supports Postgres.
Forwarded from запуск завтра
Как перезапустить проект технически?
Прямо сейчас мы решаем эту задачу для стартапа. Ребята делают платформу для ученых, чтобы проводить исследования на больших группах респондентов. Куча интеграций, огромный зоопарк форматов данных.
Они пользуются уже третьей версией своей платформы. Фронтенд на low-code платформе Bubble, бэкенд частично на flask и частично n8n. Всё работает, приносит пользу, проект поднял больше миллиона долларов инвестиций.
Как навести порядок, радикально увеличить скорость доставки фич и гарантировать масштабируемость?
Первый порыв любого программиста — переписать всё с нуля. Благо, проект ещё не очень большой, за месяца 3–4 парой программистов, наверное, можно управиться. Составить список фичей, написать их заново, потушить сервис на пару часов, импортировать данные из старой системы в новую и запуститься.
Но это — ошибка. Во-первых, мы не понимаем истинного объема бизнес-логики, который успел накопиться в коде. Скорее всего, сам клиент её недооценивает. Во-вторых, пока будем переписывать — проект продолжит развиваться. Придется догонять. В-третьих, любой, кто делал импорт данных, скажет вам, что это задача из ада, и чем старее данные — тем сложнее их вытащить. Настроить тестирование этого нового проекта будет сложно, да и полноценным оно не может быть по определению.
В результате, в момент включения новой платформы в продакшен, точно возникнут проблемы, которые придется героически исправлять «прямо сейчас», в стрессе. Мало предсказуемости, о реальном объеме работы мы узнаем только в самом конце проекта, при попытке переключения. Мы такое не любим.
Правильный ход — это strangler fig pattern. Пишем небольшую обертку для старого бэкенда. Этот новый бэкенд действует как прокси — передает запросы к старому бэкенду, запоминая сами запросы и ответы. Дальше выделяем первые эндпоинты бэкенда, которые мы можем запрограммировать заново, красиво. Дублируем эти запросы пользователей в старый и новые движки. Сравниваем ответы нового движка с ответами старого, исправляем ошибки. Накапливаем информацию в новую, аккуратно составленную базу данных. И только после продолжительного тестирования на живых данных начинаем отдавать пользователю ответы нового бэкенда. Берем следующую пачку эндпоинтов и повторяем процесс.
Получается, у нас нет момента «большого рубильника», который переключит весь трафик со старого движка на новый, мы «едим этого слона по частям». Переход со старого бэкенда на новый происходит плавно, незаметно для бизнеса. Ошибки в новой системе видны только программистам и не затрагивают клиентов.
Не менее важна предсказуемость. В первом подходе мы весь проект живем под дамокловым мечом — какие сюрпризы нас ждут при запуске? Во втором подходе мы размазываем эту неопределенность по всей продолжительности проекта, так что уже через пару недель можно увидеть реальную скорость разработки, включая исправление ошибок, и оценить общий объем работы и сроки.
Наконец, этот подход позволяет выкатывать новые фичи в продукте внутри нового бэкенда до окончания переезда, параллельно с рефакторингом.
К сожалению, кажется, что каждый молодой программист обречен пытаться всё переписать правильно с нуля. Технарь, предлагающий strangler fig pattern, не лучше, просто за его обучение уже заплатил другой заказчик.
На фотографии тот самый фикус-душитель опутывает дерево, как новый бэкенд опутывает старый.
Прямо сейчас мы решаем эту задачу для стартапа. Ребята делают платформу для ученых, чтобы проводить исследования на больших группах респондентов. Куча интеграций, огромный зоопарк форматов данных.
Они пользуются уже третьей версией своей платформы. Фронтенд на low-code платформе Bubble, бэкенд частично на flask и частично n8n. Всё работает, приносит пользу, проект поднял больше миллиона долларов инвестиций.
Как навести порядок, радикально увеличить скорость доставки фич и гарантировать масштабируемость?
Первый порыв любого программиста — переписать всё с нуля. Благо, проект ещё не очень большой, за месяца 3–4 парой программистов, наверное, можно управиться. Составить список фичей, написать их заново, потушить сервис на пару часов, импортировать данные из старой системы в новую и запуститься.
Но это — ошибка. Во-первых, мы не понимаем истинного объема бизнес-логики, который успел накопиться в коде. Скорее всего, сам клиент её недооценивает. Во-вторых, пока будем переписывать — проект продолжит развиваться. Придется догонять. В-третьих, любой, кто делал импорт данных, скажет вам, что это задача из ада, и чем старее данные — тем сложнее их вытащить. Настроить тестирование этого нового проекта будет сложно, да и полноценным оно не может быть по определению.
В результате, в момент включения новой платформы в продакшен, точно возникнут проблемы, которые придется героически исправлять «прямо сейчас», в стрессе. Мало предсказуемости, о реальном объеме работы мы узнаем только в самом конце проекта, при попытке переключения. Мы такое не любим.
Правильный ход — это strangler fig pattern. Пишем небольшую обертку для старого бэкенда. Этот новый бэкенд действует как прокси — передает запросы к старому бэкенду, запоминая сами запросы и ответы. Дальше выделяем первые эндпоинты бэкенда, которые мы можем запрограммировать заново, красиво. Дублируем эти запросы пользователей в старый и новые движки. Сравниваем ответы нового движка с ответами старого, исправляем ошибки. Накапливаем информацию в новую, аккуратно составленную базу данных. И только после продолжительного тестирования на живых данных начинаем отдавать пользователю ответы нового бэкенда. Берем следующую пачку эндпоинтов и повторяем процесс.
Получается, у нас нет момента «большого рубильника», который переключит весь трафик со старого движка на новый, мы «едим этого слона по частям». Переход со старого бэкенда на новый происходит плавно, незаметно для бизнеса. Ошибки в новой системе видны только программистам и не затрагивают клиентов.
Не менее важна предсказуемость. В первом подходе мы весь проект живем под дамокловым мечом — какие сюрпризы нас ждут при запуске? Во втором подходе мы размазываем эту неопределенность по всей продолжительности проекта, так что уже через пару недель можно увидеть реальную скорость разработки, включая исправление ошибок, и оценить общий объем работы и сроки.
Наконец, этот подход позволяет выкатывать новые фичи в продукте внутри нового бэкенда до окончания переезда, параллельно с рефакторингом.
К сожалению, кажется, что каждый молодой программист обречен пытаться всё переписать правильно с нуля. Технарь, предлагающий strangler fig pattern, не лучше, просто за его обучение уже заплатил другой заказчик.
На фотографии тот самый фикус-душитель опутывает дерево, как новый бэкенд опутывает старый.
❤3👍1
сегодня внесли небольшое с точки зрения кода улучшение, но имеющее невероятную ценность в дистанции (ака scalability и поддержка)
пришло требования организовать следующую бизнес логику:
- по UPI (читай id/urn) получить айди интеграций из сервиса А, затем по этим идентификаторам забрать сами интеграции из сервиса Б
варианты реализации:
1) 2 раунд трипа с фронта, сходить в один сервис, затем сходить в другой.
из плюсов, бекенд можно оставить as is
из минусов - двойной заход по сети, когда данные можно отдать одним запросом, в идеале еще и агрегацией на уровне бд, а не имплементацией двух запросов в разные коллекции
2) DI одного сервиса в другой, чтобы иметь возможность дернуть существующую БЛ вокруг получения некоторого интерфейса.
Плюсы: изменения связанные с обновлением БЛ локализованы в одной точке, цена поддержки 1х
минусы: сервис Б может быть раздутым (как у нас и случилось), с точки зрения композиции не понятно, почему сервису А нужен сервис Б, циклические зависимости
3) дублирование реализации получения сущности интеграции по айди в сервисе А
Плюсы: сервис Б больше не имеет прямую связь с сервисом А и может существовать независимо
минусы: очередной low-level mongoose pipeline на уровне DAL, очередной cross platform interface (IIntegrationPopulatedV1, IIntegrationPopulatedV2, IIntegrationPopulatedV3) - какой выбирать? поддержка 2х
Что с этим сделали?
Решили внедрять вертикальные слайсы, продукт стартап, команда растет, обычной горизонтальной нарезки коллекций на controller/module/service уже недостаточно, в идеале все взаимодействие с БД выносить в DAL (ооп-лайк подход, который будет инкапсулировать все взаимодействие и отличать общение с БД от БизнесЛогики). Вертикальный слайс дробит продукт на фичи. Теперь фича является холдером горизонтальных слайсов, определяем фичу, нарезаем под нее именованный сервис, в него уже инжектим composable части.
Нашли подход позволяющий скейлить и шерить логику на бекенде бесконечно, но это в теории, понаблюдаем, как это будет развиваться со временем, люблю рефлексировать над подобным опытом со временем
пришло требования организовать следующую бизнес логику:
- по UPI (читай id/urn) получить айди интеграций из сервиса А, затем по этим идентификаторам забрать сами интеграции из сервиса Б
варианты реализации:
1) 2 раунд трипа с фронта, сходить в один сервис, затем сходить в другой.
из плюсов, бекенд можно оставить as is
из минусов - двойной заход по сети, когда данные можно отдать одним запросом, в идеале еще и агрегацией на уровне бд, а не имплементацией двух запросов в разные коллекции
2) DI одного сервиса в другой, чтобы иметь возможность дернуть существующую БЛ вокруг получения некоторого интерфейса.
Плюсы: изменения связанные с обновлением БЛ локализованы в одной точке, цена поддержки 1х
минусы: сервис Б может быть раздутым (как у нас и случилось), с точки зрения композиции не понятно, почему сервису А нужен сервис Б, циклические зависимости
3) дублирование реализации получения сущности интеграции по айди в сервисе А
Плюсы: сервис Б больше не имеет прямую связь с сервисом А и может существовать независимо
минусы: очередной low-level mongoose pipeline на уровне DAL, очередной cross platform interface (IIntegrationPopulatedV1, IIntegrationPopulatedV2, IIntegrationPopulatedV3) - какой выбирать? поддержка 2х
Что с этим сделали?
Решили внедрять вертикальные слайсы, продукт стартап, команда растет, обычной горизонтальной нарезки коллекций на controller/module/service уже недостаточно, в идеале все взаимодействие с БД выносить в DAL (ооп-лайк подход, который будет инкапсулировать все взаимодействие и отличать общение с БД от БизнесЛогики). Вертикальный слайс дробит продукт на фичи. Теперь фича является холдером горизонтальных слайсов, определяем фичу, нарезаем под нее именованный сервис, в него уже инжектим composable части.
Нашли подход позволяющий скейлить и шерить логику на бекенде бесконечно, но это в теории, понаблюдаем, как это будет развиваться со временем, люблю рефлексировать над подобным опытом со временем
Forwarded from DevFM
Cursor изнутри
Недавно вышла немного рекламная, но легкая и интересная статья от The Pragmatic Engineer о том, как устроен Cursor узнутри.
В начале статьи просто любопытные цифры о Cursor. Дальше автор рассказывает нам о технологическом стеке. Из интересного:
- TypeScript – бизнес-логика, критические штуки на Rust
- Turbopuffer – основное KV-хранилище, держит зашифрованные файлы + Merkle-деревья для синка
- Pinecone – векторная БД для семантического поиска по коду
- Datadog, PagerDuty, Sentry, Amplitude для обзервабилити
- Linear – для таск трекинга (рекомендую попробовать для тех, кто не пробовал, интересное решение)
Cursor не хранит наш код на своих серверах. Когда вы отправляете запрос в Chat, происходит следующее:
1. Запрос уходит на сервер
2. Сервер решает, что это – вопрос о коде, и запускает векторный поиск по embedding'ам, которые заранее были созданы на сервере во время “индексации” проекта
3. По результатам векторного поиска сервер понимает, какие файлы могут быть релевантны и запрашивает эти конкретные файлы обратно у клиента
4. Клиент шлёт нужные части кода (зашифрованно) – только те, что реально понадобились
5. Сервер “собирает” полный контекст и запускает inference для ответа
6. Ответ возвращается в чат
Отдельно стоит рассказать, как Cursor узнаёт, какие файлы изменились, и переиндексирует только их. Для используются Merkle-деревья:
1. каждый файл разбивается на чанки, каждый чанк хешируется
2. хеши объединяются попарно и формируют узлы следующего уровня
3. в результате строится дерево, корневой хеш которого отражает состояние всего проекта – аналогичное дерево строится и на клиенте, и на сервере
Каждые ~3 минуты клиент сравнивает свой корневой хеш с серверным:
– если хеши совпадают – индекс остаётся прежним
– если отличаются – обход дерева точно выявляет изменённые чанки, и переиндексирует только их
Недавно вышла немного рекламная, но легкая и интересная статья от The Pragmatic Engineer о том, как устроен Cursor узнутри.
В начале статьи просто любопытные цифры о Cursor. Дальше автор рассказывает нам о технологическом стеке. Из интересного:
- TypeScript – бизнес-логика, критические штуки на Rust
- Turbopuffer – основное KV-хранилище, держит зашифрованные файлы + Merkle-деревья для синка
- Pinecone – векторная БД для семантического поиска по коду
- Datadog, PagerDuty, Sentry, Amplitude для обзервабилити
- Linear – для таск трекинга (рекомендую попробовать для тех, кто не пробовал, интересное решение)
Cursor не хранит наш код на своих серверах. Когда вы отправляете запрос в Chat, происходит следующее:
1. Запрос уходит на сервер
2. Сервер решает, что это – вопрос о коде, и запускает векторный поиск по embedding'ам, которые заранее были созданы на сервере во время “индексации” проекта
3. По результатам векторного поиска сервер понимает, какие файлы могут быть релевантны и запрашивает эти конкретные файлы обратно у клиента
4. Клиент шлёт нужные части кода (зашифрованно) – только те, что реально понадобились
5. Сервер “собирает” полный контекст и запускает inference для ответа
6. Ответ возвращается в чат
Отдельно стоит рассказать, как Cursor узнаёт, какие файлы изменились, и переиндексирует только их. Для используются Merkle-деревья:
1. каждый файл разбивается на чанки, каждый чанк хешируется
2. хеши объединяются попарно и формируют узлы следующего уровня
3. в результате строится дерево, корневой хеш которого отражает состояние всего проекта – аналогичное дерево строится и на клиенте, и на сервере
Каждые ~3 минуты клиент сравнивает свой корневой хеш с серверным:
– если хеши совпадают – индекс остаётся прежним
– если отличаются – обход дерева точно выявляет изменённые чанки, и переиндексирует только их
Pragmaticengineer
Real-world engineering challenges: building Cursor
Cursor has grown 100x in load in just a year, sees 1M+ QPS for its data layer, and serves billions of code completions, daily. A deepdive into how it’s built with cofounder, Sualeh Asif
👍6
Forwarded from ITKatya: культурные паттерны в IT
🏗 Как DDD помогает на этапе архитектуры и проектирования
1. Делит по смыслу, а не по слоям
DDD предлагает смотреть на систему как на совокупность смысловых контекстов, а не просто «вот тут сервис, вот тут контроллер».
Архитектура строится по бизнес-логике, а не по технологическим паттернам.
→ Вместо «сервис каталога» — «управление товарными категориями».
→ Вместо «бэк-офис» — «расчет комиссий».
📦 Это дает:
— ясные границы владения данными и логикой,
— меньше связей между частями системы,
— выше устойчивость к изменениям.
2. Позволяет не смешивать несовместимое
Если в одном модуле встречаются и бизнес-логика, и интеграции, и админ-панель, и метрики — это все пахнет монолитом боли (но не всегда! И, да, только на длительной дистанции!).
DDD подсказывает: все, что живет по разным правилам — должно жить в разных контекстах.
🧠 Пример: расчет пеней по кредитам и формирование/выдача индивидуальных кредитов — разные контексты. Разный язык, разная частота изменений, разные источники истины.
3. Как мешает (если применять неправильно)
— Переусложнение на старте
Выделять bounded context ради bounded context — вредно.
Если вы на MVP стадии и продукт еще не понял сам себя — не надо ваять архитектуру на 100 лет вперед.
— Слишком формально
DDD — это не UML и не жесткий шаблон.
Если вы пишете спецификацию на каждый value object, но не можете поговорить с бизнесом — это не DDD, это бюрократия.
4. Связь с языком и контекстами
Каждое архитектурное решение должно проходить через язык:
Если внутри одного bounded context у вас есть «user», который одновременно и платит, и нанимает, и модератор — это уже тревожный звонок.
🎯 Проверка: можно ли без ошибок перевести требования бизнеса в термины архитектуры?
5. Как проверять деление на домены и замкнутость контекстов
— Есть ли своя модель данных?
— Есть ли уникальные бизнес-правила?
— Меняются ли эти правила независимо от других частей?
— Понимает ли одна и та же команда, как это работает?
— Можно ли заменить этот контекст без масштабного рефакторинга всей системы?
Если «да» — у вас скорее всего здоровый bounded context.
🤔 Всегда ли нужно?
Нет. Если у вас микропроект на 3 человека — достаточно здравого смысла.
Но если проект растет, появляется несколько команд, увеличивается сложность, разрастается предметная область — без архитектурных принципов DDD вы начнете тонуть в хаосе.
В понедельник поговорим про разработку и реализацию, а пока:
💬 Ваша архитектура отражает бизнес? Или просто похожа на «все как у людей»?
#architecture #ddd
1. Делит по смыслу, а не по слоям
DDD предлагает смотреть на систему как на совокупность смысловых контекстов, а не просто «вот тут сервис, вот тут контроллер».
Архитектура строится по бизнес-логике, а не по технологическим паттернам.
→ Вместо «сервис каталога» — «управление товарными категориями».
→ Вместо «бэк-офис» — «расчет комиссий».
📦 Это дает:
— ясные границы владения данными и логикой,
— меньше связей между частями системы,
— выше устойчивость к изменениям.
2. Позволяет не смешивать несовместимое
Если в одном модуле встречаются и бизнес-логика, и интеграции, и админ-панель, и метрики — это все пахнет монолитом боли (но не всегда! И, да, только на длительной дистанции!).
DDD подсказывает: все, что живет по разным правилам — должно жить в разных контекстах.
🧠 Пример: расчет пеней по кредитам и формирование/выдача индивидуальных кредитов — разные контексты. Разный язык, разная частота изменений, разные источники истины.
3. Как мешает (если применять неправильно)
— Переусложнение на старте
Выделять bounded context ради bounded context — вредно.
Если вы на MVP стадии и продукт еще не понял сам себя — не надо ваять архитектуру на 100 лет вперед.
— Слишком формально
DDD — это не UML и не жесткий шаблон.
Если вы пишете спецификацию на каждый value object, но не можете поговорить с бизнесом — это не DDD, это бюрократия.
4. Связь с языком и контекстами
Каждое архитектурное решение должно проходить через язык:
— Как называется эта часть?
— Какие слова в ней допустимы?
— В каком контексте они значат то, что значат?
Если внутри одного bounded context у вас есть «user», который одновременно и платит, и нанимает, и модератор — это уже тревожный звонок.
🎯 Проверка: можно ли без ошибок перевести требования бизнеса в термины архитектуры?
5. Как проверять деление на домены и замкнутость контекстов
— Есть ли своя модель данных?
— Есть ли уникальные бизнес-правила?
— Меняются ли эти правила независимо от других частей?
— Понимает ли одна и та же команда, как это работает?
— Можно ли заменить этот контекст без масштабного рефакторинга всей системы?
Если «да» — у вас скорее всего здоровый bounded context.
🤔 Всегда ли нужно?
Нет. Если у вас микропроект на 3 человека — достаточно здравого смысла.
Но если проект растет, появляется несколько команд, увеличивается сложность, разрастается предметная область — без архитектурных принципов DDD вы начнете тонуть в хаосе.
Практические примеры (финтех):
Интернет-банк разбивается на контексты: «Accounts» (Счета), «Payments» (Платежи), «Loans» (Кредиты), «Cards» (Карты), «Analytics/Reporting» (Отчеты). Каждый из них соответствует своей части бизнеса и управляется отдельной командой. Например, команда контекста Payments владеет всем, что связано с переводами: у них свой словарь (платеж, транзакция, комиссионные и т.д.) и своя кодовая база. В другом контексте Accounts – свой словарь (баланс, счет, клиент и т.п.). Эти команды работают параллельно, а взаимодействуют их сервисы через четко определенные API. При этом термин «Transaction» в контексте платежей имеет одно значение (конкретное движение денег), а в контексте аналитики, скажем, это может быть абстрактный объект для агрегированной статистики. Благодаря DDD эти понятия разведены: без выделения контекстов компания получила бы единую громоздкую систему, где разные отделы говорили бы «транзакция» о разном и путали друг друга.
В этом примере команда Accounts и команда Payments могут работать автономно, выпуская изменения независимо – изменение в сервисе счетов не сломает сервис платежей, если контракт (например, API запроса баланса) остался прежним.
В понедельник поговорим про разработку и реализацию, а пока:
💬 Ваша архитектура отражает бизнес? Или просто похожа на «все как у людей»?
#architecture #ddd
👍3
Forwarded from Evgeniy Pyatkov
Подскажи, я попробовал copilot, он мне сильно помог с написанием прослойки для фронта. Но вот думаю теперь, что попробовать еще, в copilot вроде уже завезли gpt-5, стоит ли оставаться на нем. Или лучше перейти на cursor?
Шикарный вопрос! Смотри, есть ещё одна очень важная деталь, которую нужно понимать при выборе агента: агенты отличаются не только по фичам.
То есть, сейчас очевидно, что Cursor — явный лидер по фичам: его автодополнение с помощью табов единственное, которое корректно работает на всём рынке, в нём доступны все модели, которыми ты когда-либо захочешь воспользоваться, у него есть скидки на использование моделей т.е. платишь $60, получаешь лимиты на $70, также есть фоновые агенты, Max Mode с расширенным контекстом, огромное коммьюнити, автоматическая генерация рулзов. В общем, все остальные агенты по фичам сейчас находятся в роли догоняющих. Ситуация настолько патовая, что бэкендеры генерируют ответы в Cursor, а пишут код в Rider IDE... Стоп, что? Зачем бэкендеры так делают, если у них доступен Windsurf в виде плагина?... Давай разбираться)
Прежде всего есть разные варианты того, как можно собрать контекст по проекту. Сейчас, правда, все поголовно используют RAG, так как его проще всего реализовать, но помяни мои слова первый агент, который научится строить Knowledge Graphs на основе кодовой базы вырвется вперёд в этой гонке. Проблема RAG как раз в том, что он не умеет работать с большими кусками данных, не умеет связывать сущности то есть RAG слабо понимает как TooltipContainer и TooltipIcon связаны между собой, но уже сейчас, не особо понимая, как части проекта связаны между собой он выдаёт достаточно хорошие ответы, чтобы мы могли сильно ускориться, представь что случится, когда агенты будут чётко понимать как разные части кода связаны между собой:)
Это было небольшое лирическое отступление, но оно позволяет хорошо понять, что изнутри агенты могут быть сильно по-разному устроены. Конкретно то, что уже сейчас используют разработчики агентов и основная их фишка — fine tunning. Каждый агент пишет разные промпты, чтобы модель могла выполнить твою задачу. И добавление новой модели требует глубокого понимания того, как она устроена. Сейчас GPT-5 в самом худшем состоянии, в котором мы её когда-либо увидим в агентах, но не потому что OpenAI её доработает (хотя, и такое возможно, конечно), а потому что её нужно зафаинтюнить, чтобы она корректно работала. Почему это не понадобилось делать при переходе с Claude 3.7 на Claude 4? Просто потому что это та же самая модель, но на условные 20% лучше, в то время как GPT-5 — модель нового поколения и к ней тот фаинтюнинг, что был применим ко всем прошлым моделям GPT просто не применим, поэтому пока разработчики агентов не поймут как отфаинтюнить GPT-5 мы будем наблюдать различные артефакты. Почему я предлагаю переходить на Cursor и почему бэкендеры используют Cursor, когда есть возможность пересесть на Windsurf? Ребята из Cursor лучше всего фаинтюнят модели и прямо сейчас теснее всех работают с OpenAI, для того чтобы затащить лучший экспириенс для GPT-5, какой они могут. Тут ещё важно сказать, что мы не получили идеальную ✨интеграцию GPT-5 в Cursor со старта, потому что сами OpenAI не понимают как их модель работает (в целом, это относится ко всем компаниям и моделям, просто правда такова, что мы не понимаем как работает ИИ под капотом и чем дальше, тем больше будем не понимать).
Так что ответ на твой изначальный вопрос — однозначно переходи на Cursor)
Ты получается не подписку юзаешь, а чисто по токенам?
До появления GPT-5 сидел на подписке, но сейчас планирую перейти на токены, так как в этом действительно появился смысл. Ту статистику по расходам, которую я приводил я просто брал из админки Cursor, она была нужна мне для своего исследования фактической стоимости моделей)
Похоже пора заводить свой канал про ИИ 😅
👍5😁2❤1🔥1
Forwarded from Стой под стрелой (Nikita Prokopov)
Короче, я подумал и все-таки самая главная вещь, которую я хочу от языка программирования/окружения — это писать все в одном месте.
Вспомните, когда программирование приносило вам наибольшую радость? Когда написал локальную программу, запустил тут же и она работает. Все локально, память общая, все средства языка работают, вызвать функцию или передать тривиально. Ничто, я повторяю, НИЧТО в жизни не приносит большего удовольствия, чем писать локальную программу. Поэтому программисты так любят переписывать и без того уже хорошие CLI утилиты на Rust — это тупо приятно.
Ну вот. Потом пришел веб, и мы потеряли невинность. Появилась трехзвенная архитектура (фронт-сервер-база), и многие решили, что так и нужно. Уверен, кто-нибудь по сей день готов с пеной у рта доказывать, что это хорошая архитектура, что ее не дураки придумывали, что по-другому нельзя все равно, и что я не разобрался. И на деле — ну да, она работает. Но ценой сложности. Она усложнила программирование.
В чем сложность? Все эти компоненты написаны по-разному (исторически сложилось) и не особо разговаривают друг с другом. Бэкенд функцию уже так просто не позовешь с фронтенда. В базу не сходишь без церемоний.
Даже языков стало несколько. Приложения уже не написаны на С++. Они написаны на JS + Python + PLSQL + черт знает что еще. Где язык, там и стек. Нужны АПИ, сериализация, кубернетесы, а это куча дополнительной работы. Для джоб секьюрити хорошо, конечно.
Появилось разделение программистов — фронтендеры, бэкендеры, мобильщики. Каждая часть стека стала настолько сложной, что за карьеру ты можешь освоить что-то одно. Как результат, один человек уже не может написать программу целиком (или, если может, то ох как заебется). Накидать проектик на выходных тоже не слишком просто. Если это не команд-лайн утилита, конечно. Программы, которые писать приятно, никому не нужны, а программы, которые нужны людям, писать сложно. Противоречие-с.
Ну вот. А теперь возвращаемся к исходной посылке. Как сделать программирование снова приятным? Нужно писать все в одном месте. Чтобы не нужно было пяти языков. Чтобы все со всем работало, дружило, разговаривало. Чтобы доступ был прозрачный и унифицированный. Чтобы все было встроено — и база данных, и UI.
Звучит фантастично? Ну и что. Почему нет? Мне очевидно, что это кардинально снизит сложность создания программ. И сложность управления программами. Да, эволюционно мы пришли в совсем другую точку, где каждая часть стека развивалась сама по себе. В итоге ты получаешь симулятор шизофреника: так, на каком языке я сейчас пишу? Как тут ставятся комментарии? Camel case или snake?
Вместо этого можно знаете что? Проигнорировать всю эту инженерную мудрость и сразу пойти в ту точку, в которую мы хотим. Вроде цель ясна. Фундаментальных препятствий, вроде, никаких нет.
Вспомните Darklang. Если я правильно понимаю, ты заходил к ним на страничку, открывался редактор и ты правил систему. Все. Что ты там наисправлял, то и сервится наружу через HTTP эндпоинты. Деплоя нет. Коммита даже нет. Ничто никуда не нужно пересылать, нигде данные не нужно перекидывать через забор. Звучит фантастически. Но пруф концепта работал (потом, правда, деньги закончились).
Только у Darklang не было никакой UI истории. А UI тоже должен быть встроен, и встроен нормально, с интеграцией в сервер, с доступом в базу. Это не должно выглядеть как миллион веб-макак, пишущих очередной компонент с тридцатью хуками, единственная цель которого — превратить React в HTML, который в свою очередь соберет JSON, чтобы сходит в сеть на сервер, который соберет SQL, чтобы сходить за вас в базу. И все это нужно, чтобы на эране появилась цифра, сколько программистов получают зарплату в отделе. Когда я думаю, сколько бессмысленной, никому не нужной работы происходит в этой цепочке и что многие люди считают это state of the art и ничего плохого в такой архитектуре не видят...
Елси программирование будущего будет выглядеть так, то лучше сразу отрубите мне пальцы. По самую шею.
Вспомните, когда программирование приносило вам наибольшую радость? Когда написал локальную программу, запустил тут же и она работает. Все локально, память общая, все средства языка работают, вызвать функцию или передать тривиально. Ничто, я повторяю, НИЧТО в жизни не приносит большего удовольствия, чем писать локальную программу. Поэтому программисты так любят переписывать и без того уже хорошие CLI утилиты на Rust — это тупо приятно.
Ну вот. Потом пришел веб, и мы потеряли невинность. Появилась трехзвенная архитектура (фронт-сервер-база), и многие решили, что так и нужно. Уверен, кто-нибудь по сей день готов с пеной у рта доказывать, что это хорошая архитектура, что ее не дураки придумывали, что по-другому нельзя все равно, и что я не разобрался. И на деле — ну да, она работает. Но ценой сложности. Она усложнила программирование.
В чем сложность? Все эти компоненты написаны по-разному (исторически сложилось) и не особо разговаривают друг с другом. Бэкенд функцию уже так просто не позовешь с фронтенда. В базу не сходишь без церемоний.
Даже языков стало несколько. Приложения уже не написаны на С++. Они написаны на JS + Python + PLSQL + черт знает что еще. Где язык, там и стек. Нужны АПИ, сериализация, кубернетесы, а это куча дополнительной работы. Для джоб секьюрити хорошо, конечно.
Появилось разделение программистов — фронтендеры, бэкендеры, мобильщики. Каждая часть стека стала настолько сложной, что за карьеру ты можешь освоить что-то одно. Как результат, один человек уже не может написать программу целиком (или, если может, то ох как заебется). Накидать проектик на выходных тоже не слишком просто. Если это не команд-лайн утилита, конечно. Программы, которые писать приятно, никому не нужны, а программы, которые нужны людям, писать сложно. Противоречие-с.
Ну вот. А теперь возвращаемся к исходной посылке. Как сделать программирование снова приятным? Нужно писать все в одном месте. Чтобы не нужно было пяти языков. Чтобы все со всем работало, дружило, разговаривало. Чтобы доступ был прозрачный и унифицированный. Чтобы все было встроено — и база данных, и UI.
Звучит фантастично? Ну и что. Почему нет? Мне очевидно, что это кардинально снизит сложность создания программ. И сложность управления программами. Да, эволюционно мы пришли в совсем другую точку, где каждая часть стека развивалась сама по себе. В итоге ты получаешь симулятор шизофреника: так, на каком языке я сейчас пишу? Как тут ставятся комментарии? Camel case или snake?
Вместо этого можно знаете что? Проигнорировать всю эту инженерную мудрость и сразу пойти в ту точку, в которую мы хотим. Вроде цель ясна. Фундаментальных препятствий, вроде, никаких нет.
Вспомните Darklang. Если я правильно понимаю, ты заходил к ним на страничку, открывался редактор и ты правил систему. Все. Что ты там наисправлял, то и сервится наружу через HTTP эндпоинты. Деплоя нет. Коммита даже нет. Ничто никуда не нужно пересылать, нигде данные не нужно перекидывать через забор. Звучит фантастически. Но пруф концепта работал (потом, правда, деньги закончились).
Только у Darklang не было никакой UI истории. А UI тоже должен быть встроен, и встроен нормально, с интеграцией в сервер, с доступом в базу. Это не должно выглядеть как миллион веб-макак, пишущих очередной компонент с тридцатью хуками, единственная цель которого — превратить React в HTML, который в свою очередь соберет JSON, чтобы сходит в сеть на сервер, который соберет SQL, чтобы сходить за вас в базу. И все это нужно, чтобы на эране появилась цифра, сколько программистов получают зарплату в отделе. Когда я думаю, сколько бессмысленной, никому не нужной работы происходит в этой цепочке и что многие люди считают это state of the art и ничего плохого в такой архитектуре не видят...
Елси программирование будущего будет выглядеть так, то лучше сразу отрубите мне пальцы. По самую шею.
🔥3👍1
Знали ли вы историю Slack, который настолько заоверинжинирил чат для игры, что они стали его использовать внутри компании и написали для него веб апп следом, затем собрал десктоп на электроне, что уже потом начали это продавать?
Вот и я не знал
не стесняйтесь оверинжинирить, возможно, это принесет миллиарды денег вам, ну или вашей компании
Вот и я не знал
не стесняйтесь оверинжинирить, возможно, это принесет миллиарды денег вам, ну или вашей компании
😁5
ну а так, если по-честному, я не вижу себя без сложных задач которые ломают меня, будь это задачи по построению интерфейсов даже, оно придает хоть какой-то смысл будням и рутине, которая потребляет столько часов из моей жизни, не знаю как бы я жил без этого, и как славно, что на каждой работе я нахожу что-то такое, заставляющее меня трепетать и бесконечно думать, итерироваться, рефакторить и что-то менять, архитектором что ли стать
а что вас радует в рабочей рутине?
а что вас радует в рабочей рутине?
❤8💯1
нашел сегодня токенайзер, можно смотреть на какие токены разбивается ваш пропмт (ну или респонс)
https://platform.openai.com/tokenizer
https://platform.openai.com/tokenizer
🔥5
Forwarded from Будни разработчика (Sergey Bekharsky)
#инструмент дня
Да-да, я в курсе, что писать SQL-запросы, возможно, не самая частая компетенция у фронтендеров, но мы же все хотим узнавать новое, не правда ли?
А запросы ведь могут стать достаточно сложными. Конечно, есть EXPLAIN, но его вывод по сложности может сравниться с самим запросом. Если не сложнее.
К счастью, есть визуальные инструменты! И одним из таких является MySQL Visual Explain.
Уникальное название, согласен.
Ссылка: https://mysqlexplain.com/
Рекомендую посмотреть примеры и попробовать самим, если MySQL является частью вашего стека.
Кстати, у них даже API есть, одним из примеров использования является плагин для Laravel: https://github.com/tpetry/laravel-mysql-explain
То есть, вариант использования может быть таким:
1. Прогнали интеграционные тесты
2. Нашли медленные запросы с помощью telescope
3. Отправили их на визуальный анализ
4. ...
5. Пофиксили!
Да и для обучения — бесценно.
#mysql #explain #laravel #бородач
Да-да, я в курсе, что писать SQL-запросы, возможно, не самая частая компетенция у фронтендеров, но мы же все хотим узнавать новое, не правда ли?
А запросы ведь могут стать достаточно сложными. Конечно, есть EXPLAIN, но его вывод по сложности может сравниться с самим запросом. Если не сложнее.
К счастью, есть визуальные инструменты! И одним из таких является MySQL Visual Explain.
Уникальное название, согласен.
Ссылка: https://mysqlexplain.com/
Рекомендую посмотреть примеры и попробовать самим, если MySQL является частью вашего стека.
Кстати, у них даже API есть, одним из примеров использования является плагин для Laravel: https://github.com/tpetry/laravel-mysql-explain
То есть, вариант использования может быть таким:
1. Прогнали интеграционные тесты
2. Нашли медленные запросы с помощью telescope
3. Отправили их на визуальный анализ
4. ...
5. Пофиксили!
Да и для обучения — бесценно.
#mysql #explain #laravel #бородач
🔥3
Forwarded from запуск завтра
Открыл для себя, что аренда или покупка IP-адресов — это, оказывается, не совсем черная магия. Есть специальные площадки IPXO и InterLIR, где за примерно 100 баксов в месяц можно арендовать подсеть из 255 адресов, а за тысяч 10 — и купить.
Узнал об этом, когда обсуждали с коллегами блокировку Cloudflare. Мол, не обязательно терять российских пользователей или хоститься в России, достаточно арендовать подсеть и передать её под управление Cloudflare (BYOIP). Таким образом, не попадаешь под ковровые блокировки РКН и при этом можешь пользоваться всеми плюшками ведущего международного CDN. Правда, эта услуга доступна только на корпоративном тарифном плане, который, по слухам, стоит от 4 тысяч долларов в месяц.
Не думаю, что это много кому полезно, но интересно. Мне казалось, что купить подсеть
P. S. Власти блокируют Cloudflare, потому что он поддерживает новые протоколы ECH и QUIC, которые не расшифровываются коробочками ТСПУ Роскомнадзора. Получается как с ютубом, где не могут заблокировать отдельные видео, поэтому блокируют сервис целиком.
Узнал об этом, когда обсуждали с коллегами блокировку Cloudflare. Мол, не обязательно терять российских пользователей или хоститься в России, достаточно арендовать подсеть и передать её под управление Cloudflare (BYOIP). Таким образом, не попадаешь под ковровые блокировки РКН и при этом можешь пользоваться всеми плюшками ведущего международного CDN. Правда, эта услуга доступна только на корпоративном тарифном плане, который, по слухам, стоит от 4 тысяч долларов в месяц.
Не думаю, что это много кому полезно, но интересно. Мне казалось, что купить подсеть
/24 — это что-то, что могут сделать только «настоящие провайдеры» или «серьезные компании, типа Яндекса». Оказалось, и тут не боги горшки обжигают.P. S. Власти блокируют Cloudflare, потому что он поддерживает новые протоколы ECH и QUIC, которые не расшифровываются коробочками ТСПУ Роскомнадзора. Получается как с ютубом, где не могут заблокировать отдельные видео, поэтому блокируют сервис целиком.
🤯2
Forwarded from Eugene Bosiakov
1. У больших клиентов свои цены, никак не связанные с паблик-ценами.
2. Запросы больших клиентов измеряются в тысячах - тысячи vcpu, тысяч терабайт на хранилище. Не-у-клауд-провайдеров весь капасити может быть меньше, чем скейл нетфликса/зума/роблокса в течении дня.
3. AWS продает в первую очередь pay-as-you-play модель.
Реально большие бизнесы имеет какую-то синусоиду трафика в течении дня и могут высвобождать ресурсов на тысячи цпу. В комбинации с приватными ценами это обеспечивает финмодель, которую никто больше не даст.
Все остальное булшит от сейлов.
2. Запросы больших клиентов измеряются в тысячах - тысячи vcpu, тысяч терабайт на хранилище. Не-у-клауд-провайдеров весь капасити может быть меньше, чем скейл нетфликса/зума/роблокса в течении дня.
3. AWS продает в первую очередь pay-as-you-play модель.
Реально большие бизнесы имеет какую-то синусоиду трафика в течении дня и могут высвобождать ресурсов на тысячи цпу. В комбинации с приватными ценами это обеспечивает финмодель, которую никто больше не даст.
Все остальное булшит от сейлов.
https://nekrolm.github.io/blog.html
узнали себя? кто еще не успел выгореть - блог пост от разраба, который 3 года трудился на AWS, на русском
узнали себя? кто еще не успел выгореть - блог пост от разраба, который 3 года трудился на AWS, на русском
❤2
Forwarded from запуск завтра
Подъехал пост-мортем от Амазона.
С одной стороны, хочется поржать над DNS Enactor, DropletWorkflow Manager (DWFM), Network Manager и прочими — это Galactic от Krazam, только в реальном мире и на очень серьезных щщах.
Если без шуток, то цепочка такая:
Раздел «что мы поменяем» удивительно короткий и очень технический: починят рейс кодишен в DNS, ограничат объем серверов, который может выключить лоад-балансер и т. д. Ну и заканчивают «извините, в будущем будем более лучше стараться».
Интересно, что они не делают никаких философских выводов из ситуации. Видимо, считают, что идейно всё верно. Я сам такими огромными системами (и командами) не управлял и поэтому осторожно предположу, что, наверное, технически, можно сделать систему проще, но учитывая, что над ней работают десятки независимых команд — это, наверное, минимальный доступный объем сложности и допустимый объем ошибок. Было бы интересно услышать мнение «настоящих сварщиков».
—
Коллеги советуют замечательную статью на тему безопасности сложных систем. Она не дает ответов, но предостерегает от попытки найти «root cause», «причину аварии» и предлагает посмотреть на безопасность систем по-новому, через другие линзы, чем я привык. Очень рекомендую.
С одной стороны, хочется поржать над DNS Enactor, DropletWorkflow Manager (DWFM), Network Manager и прочими — это Galactic от Krazam, только в реальном мире и на очень серьезных щщах.
Если без шуток, то цепочка такая:
1. сначала сломался доступ к dynamodb из-за рейс-кондишена системы управления DNS — два таска начали писать в DNS одновременно, первый старую версию записей, второй — более новую новую, в результате часть записей в DNS оказалась новая, часть старая, второй процесс запустил cleanup, который удалил все старые записи и из такого разломанного состояния система сама восстановиться не могла. Сломалось в полночью, за 50 минут поняли в чем дело и ещё за 40 минут починили руками.
2. из-за сломанного dynamodb, система управления железом не могла обновить статус физических серверов и начала отмечать их как «недоступные», поэтому не могла запустить новые виртуальные машины; после восстановления dynamodb, по-идее всё должно было встать само, но из-за большого объема железа, стоящего в очереди, обновление статуса занимало дольше, чем таймаут — и очередь не разгребалась, а только росла. Коллапс. Стандартной процедуры восстановления для такого случая прописано не было, через 2 часа попыток что-то разрулить, инженеры ограничили число входящих запросов и начали перезапускать тачки с системой управления; это помогло, теперь можно было создать новые виртуальные машины;
3. но ещё какое-то время эти новые виртуалки не делали никакой полезной работы, потому что из-за взрывной нагрузки не справлялась система управления разлива конфигурации сети и сеть на новые тачки приходила с задержкой;
4. из-за этой задержки появления сети на машинах, моргали статусы серверов в лоад-балансерах, отмечая живые инстансы как мертвые и триггерились дополнительные переключения нагрузки (привет, DNS!) и перегрузилась система проверки здоровья серверов,
пришлось её на время выключить.
Ну а когда у вас не доступны базы данных и виртуальные машины, то все остальное уже валится по цепочке (и список десятков облачных сервисов, которые пострадали).
Раздел «что мы поменяем» удивительно короткий и очень технический: починят рейс кодишен в DNS, ограничат объем серверов, который может выключить лоад-балансер и т. д. Ну и заканчивают «извините, в будущем будем более лучше стараться».
Интересно, что они не делают никаких философских выводов из ситуации. Видимо, считают, что идейно всё верно. Я сам такими огромными системами (и командами) не управлял и поэтому осторожно предположу, что, наверное, технически, можно сделать систему проще, но учитывая, что над ней работают десятки независимых команд — это, наверное, минимальный доступный объем сложности и допустимый объем ошибок. Было бы интересно услышать мнение «настоящих сварщиков».
—
Коллеги советуют замечательную статью на тему безопасности сложных систем. Она не дает ответов, но предостерегает от попытки найти «root cause», «причину аварии» и предлагает посмотреть на безопасность систем по-новому, через другие линзы, чем я привык. Очень рекомендую.
🔥3