Когда смотришь, как сделаны логи в других системах, понимаешь, насколько круто реализованы логи в Java. Вот смотрите, основная проблема: у тебя есть какая-то библиотека, в которой есть логи. Есть два варианта, как их делать: забить и просто всегда выводить в консоль, либо ты каким-то образом предоставляешь клиенту возможность использовать свой логер.
В мире бэкенд-разработки на Java, разработчики сели, подумали и решили: а давайте сделаем общий интерфейс логов, на который все будут завязаны, и чтобы была возможность в runtime подставить реализацию, удобную клиенту. Так появился SLF4J. Поэтому все библиотеки для Java завязываются на SLF4J, и если у вас в проекте уже настроен логгер, он автоматически будет работать с этой библиотекой – весьма удобно.
В мире Android все либо используют Timber (или какой-то мультиплатформенный аналог), либо делают что-то свое. Библиотеки в основном предоставляют какой-то интерфейс для логов, например, Interceptor в OkHttp. Общего решения может и нет, но жить можно.
Однако в мире js все гораздо забавнее. Я делал сервис с использованием Next.js. Эти ребята вообще не заморачиваются с логированием, они просто выводят все в консоль. Нет никаких стандартных инструментов, чтобы это исправить. Что если мне нужно не в консоль, а в файл? Что если мне нужен особый формат? Вообще похую.
Решается это интересным способом. Так как JavaScript весь из себя такой гибкий, можно просто переопределить стандартную функцию вызова консоли на свою функцию, в которой мы уже вызываем нормальный логгер.
Ох уж эти фронтендеры, казалось бы, простая вещь, которая уже решена, но даже тут возникают сложности.
В мире бэкенд-разработки на Java, разработчики сели, подумали и решили: а давайте сделаем общий интерфейс логов, на который все будут завязаны, и чтобы была возможность в runtime подставить реализацию, удобную клиенту. Так появился SLF4J. Поэтому все библиотеки для Java завязываются на SLF4J, и если у вас в проекте уже настроен логгер, он автоматически будет работать с этой библиотекой – весьма удобно.
В мире Android все либо используют Timber (или какой-то мультиплатформенный аналог), либо делают что-то свое. Библиотеки в основном предоставляют какой-то интерфейс для логов, например, Interceptor в OkHttp. Общего решения может и нет, но жить можно.
Однако в мире js все гораздо забавнее. Я делал сервис с использованием Next.js. Эти ребята вообще не заморачиваются с логированием, они просто выводят все в консоль. Нет никаких стандартных инструментов, чтобы это исправить. Что если мне нужно не в консоль, а в файл? Что если мне нужен особый формат? Вообще похую.
Решается это интересным способом. Так как JavaScript весь из себя такой гибкий, можно просто переопределить стандартную функцию вызова консоли на свою функцию, в которой мы уже вызываем нормальный логгер.
Ох уж эти фронтендеры, казалось бы, простая вещь, которая уже решена, но даже тут возникают сложности.
🗿21👍5😁5❤2🔥1🤔1
Совет дня: на тренировках в зале лучше использовать большие наушники вместо AirPods. Я уже сбился со счета, сколько раз меня спасал ободок наушников от того, что я куда-то вьебался.
В программировании аналогом больших наушников является строгая типизация.
В программировании аналогом больших наушников является строгая типизация.
🔥43😁27❤4🤔3🥰2
Сейчас с развитием LLM-агентов многие говорят, что программирование со временем очень сильно изменится. Оно будет больше похоже не на набор текста, а на что-то вроде игры в StarCraft, где у тебя куча юнитов (агентов) выполняют какие-то мелкие задачи, а ты выступаешь в роли стратега, занимаясь лишь разработкой архитектуры.
В целом это и сейчас можно сделать, только вот как это выглядит на практике: ты говоришь юниту идти добывать золото. Он идет добывать золото, затем почему-то переключается на добычу дерева. После вообще уходит на вражескую базу и добывает золото там. Затем идет к середине карты и пытается дать пизды NPC, а после возвращается на базу и начинает ходить по кругу.
В целом это и сейчас можно сделать, только вот как это выглядит на практике: ты говоришь юниту идти добывать золото. Он идет добывать золото, затем почему-то переключается на добычу дерева. После вообще уходит на вражескую базу и добывает золото там. Затем идет к середине карты и пытается дать пизды NPC, а после возвращается на базу и начинает ходить по кругу.
😁69👍5🥰1
Мне нравился Arc как минимум за две функции:
👉 Можно было скопировать ссылку на страницу просто по Command + Shift + C. Возможно, в других браузерах есть то же самое, но я пока не нашел.
👉 Очень плавно работал Picture-in-Picture. Когда я в последний раз пробовал использовать эту функцию в Chrome, он не мог показывать PiP поверх других окон на Mac, а Arc — мог.
Из минусов, из-за того что панель управление находится сбоку, очень многие сайты сходили с ума, т.к не верстались под такое.
Когда Arc только появился, у них был встроенный AI-поисковик, но с появлением Perplexity необходимость в нём отпала.
Видимо, придётся возвращаться обратно в Safari. Чтош...
P.S. а ну и логин при старте конечно бесил жутко, тупее этого делать только логин в терминале
👉 Можно было скопировать ссылку на страницу просто по Command + Shift + C. Возможно, в других браузерах есть то же самое, но я пока не нашел.
👉 Очень плавно работал Picture-in-Picture. Когда я в последний раз пробовал использовать эту функцию в Chrome, он не мог показывать PiP поверх других окон на Mac, а Arc — мог.
Из минусов, из-за того что панель управление находится сбоку, очень многие сайты сходили с ума, т.к не верстались под такое.
Когда Arc только появился, у них был встроенный AI-поисковик, но с появлением Perplexity необходимость в нём отпала.
Видимо, придётся возвращаться обратно в Safari. Чтош...
P.S. а ну и логин при старте конечно бесил жутко, тупее этого делать только логин в терминале
❤8🥰1🤯1
Forwarded from addmeto (Grigory Bakunov)
В этот раз не шутят: закрывается браузер Arc. Да, тот самый "новый, перспективный, самый лучший", однако совершенно непонятно для кого сделанный браузер. Среди гиков пользователей было много, к сожалению, это самая неблагодарная аудитория.
Честно говоря, я с самого начала был против Arc ровно по этой причине — неясно, как выживет такой продукт и ради чего его поддерживать. У меня есть еще с десяток таких продуктов, под флагом "не инвестировать время в освоение интерфейса того, что умрет, т.к. выжить не сможет". Обычно из этого списка умирает 2-3 проекта в год.
Такие продукты не бесполезны, они двигают прогресс вперед. Я просто не советую людям инвестировать свои силы и время в то, что нужно только ради прогресса.
https://t.me/blognot/6026
Честно говоря, я с самого начала был против Arc ровно по этой причине — неясно, как выживет такой продукт и ради чего его поддерживать. У меня есть еще с десяток таких продуктов, под флагом "не инвестировать время в освоение интерфейса того, что умрет, т.к. выжить не сможет". Обычно из этого списка умирает 2-3 проекта в год.
Такие продукты не бесполезны, они двигают прогресс вперед. Я просто не советую людям инвестировать свои силы и время в то, что нужно только ради прогресса.
https://t.me/blognot/6026
Telegram
БлоGнот
The Browser Company объявила (опять) о закрытии разработки браузера Arc и переходе к новому проекту — AI-браузеру Dia. Основатель Джош Миллер признал три ключевые ошибки: слишком долго работали над Arc, несмотря на очевидные проблемы с ростом и удержанием…
👍5🤯2👎1🥰1
По многочисленным заявкам (одной) я решил сделать серию постов про то, с чем в основном работаю последние несколько лет, а именно про CI/CD. Расскажу в целом про базу для тех, кто вообще это не трогал:
👉 Что такое пайплайн из чего состоит
👉 Как запускаются пайплайны и где выполняются
👉 Что такое self-hosted runner
👉 Как артефакты передаются между job
👉 Как работают UI тесты на CI
Для продвинутых:
👉 Варианты как ускорить пайплайны
👉 Подходы для отладки пайплайнов
👉 Какие задачи лучше не делать в CI
Поэтому не переключайтесь. Начало туть
👉 Что такое пайплайн из чего состоит
👉 Как запускаются пайплайны и где выполняются
👉 Что такое self-hosted runner
👉 Как артефакты передаются между job
👉 Как работают UI тесты на CI
Для продвинутых:
👉 Варианты как ускорить пайплайны
👉 Подходы для отладки пайплайнов
👉 Какие задачи лучше не делать в CI
Поэтому не переключайтесь. Начало туть
🔥105❤14👍2👏2
Forwarded from MyGap
Еще один дикий пример, как мы катимся к киберпанку и технологическому шоку.
Ютуб начал раскатывать автоматический дубляж в видео. Еще раз: АВТОМАТИЧЕСКИЙ ПЕРЕВОД твоей аудиодорожки.
То есть ты загружаешь свою обычную дорожку, где ты говоришь, например, на русском языке. Программулина ютуба каким-то магическим образом распознает звуки, которые ты говоришь.
Затем эти звуки она умеет имитировать, как умный попугай. А точнее - не просто имитировать, а предварительно переводит на другой язык, меняет твою оригинальную дорожку и выдает зрителю переведенную имитацию
Тут отдельный ВАУ в том, что в ходе имитации звуков она оставляет ТВОЙ ГОЛОС. То есть блогер говорит на незнакомом ему языке на уровне носителя, без акцента. Это очень прикольно. Очень киберпанково и вообще прям слов нет, крч.
Мне лично очень интересно, когда на нашем канале такую фичу раскатают, и я смогу услышать свою же английскую речь без акцента. Ну или японскую.
А пока у нас такого нет, можете заценить у американского Вилсакома. Прям попрыгайте по аудиодорожкам. Даже на русском говорит прекрасно
https://youtu.be/jXJODqfaJto?si=MInGXsPmwP18bQb6
UPD: по предыдущей ссылке аудио переведено отдельно… но тоже в ИИ сервисе. Не человеком. И вставлено благодаря фиче мультидорожек от ютуба
Ютубовский же перевод можно посмотреть тут https://youtu.be/AHDvVhfU1Og?si=pqjKkrFLTk47rRQy
Там языков больше, но качество пока хуже. Ключевое - пока
Ютуб начал раскатывать автоматический дубляж в видео. Еще раз: АВТОМАТИЧЕСКИЙ ПЕРЕВОД твоей аудиодорожки.
То есть ты загружаешь свою обычную дорожку, где ты говоришь, например, на русском языке. Программулина ютуба каким-то магическим образом распознает звуки, которые ты говоришь.
Затем эти звуки она умеет имитировать, как умный попугай. А точнее - не просто имитировать, а предварительно переводит на другой язык, меняет твою оригинальную дорожку и выдает зрителю переведенную имитацию
Тут отдельный ВАУ в том, что в ходе имитации звуков она оставляет ТВОЙ ГОЛОС. То есть блогер говорит на незнакомом ему языке на уровне носителя, без акцента. Это очень прикольно. Очень киберпанково и вообще прям слов нет, крч.
Мне лично очень интересно, когда на нашем канале такую фичу раскатают, и я смогу услышать свою же английскую речь без акцента. Ну или японскую.
А пока у нас такого нет, можете заценить у американского Вилсакома. Прям попрыгайте по аудиодорожкам. Даже на русском говорит прекрасно
https://youtu.be/jXJODqfaJto?si=MInGXsPmwP18bQb6
UPD: по предыдущей ссылке аудио переведено отдельно… но тоже в ИИ сервисе. Не человеком. И вставлено благодаря фиче мультидорожек от ютуба
Ютубовский же перевод можно посмотреть тут https://youtu.be/AHDvVhfU1Og?si=pqjKkrFLTk47rRQy
Там языков больше, но качество пока хуже. Ключевое - пока
🔥15❤3🤯2
Я планировал начать с пайплайнов, но решил: давайте сначала разберемся с самой аббревиатурой CI/CD. Фишка в том, что под этими аббревиатурами подразумевают уже не то, что изначально закладывалось. Сейчас при упоминании CI/CD в голове всплывают скорее системы GitLab CI, Actions, Kubernetes или Docker. Однако все эти системы на самом деле лишь вспомогательные инструменты.
Continuous Integration — постоянная интеграция. Возникает вопрос: интеграция чего во что? Мы все работаем с кодом и, вероятнее всего, работаем в какой-то команде. Когда мы делаем какие-то изменения, то должны эти изменения распространить на других участников команды, а также получить изменения от них.
Сейчас для этого повсеместно используется Git. У тебя есть локальная версия кода, изменения в которой ты отправляешь на удаленный сервер. Другими словами, ты "интегрируешь" свои изменения с изменениями других участников.
Понимаете суть? Если у тебя настроен Git и есть практика условно раз в день отправлять свои изменения и получать изменения от остальных членов команды, у тебя уже в некотором смысле есть CI.
Вокруг этой идеи затем строится процесс, чтобы правильно внедрить наши изменения: хорошо бы их сначала проверить — прогнать линтер, прогнать тесты, сделать сборку. Ну и еще перед интеграцией наших изменений, чтобы наша команда эти изменения просмотрела, отсюда мы получаем код-ревью.
Continuous Delivery — постоянное развертывание. Этот принцип уже исходит из следующей проблемы. Вот есть разработка, которая пишет код, создает систему. И есть команда, отвечающая за развертывание. Проблема в коммуникации между этими двумя группами: одна группа жалуется на "тупых админов", вторая — на "криворуких разработчиков".
Помимо этого, софт раньше поставлялся четкими версиями. Вот выпустили вы ПО версии 2, и все, ближайшие пару лет будете на ней сидеть. Ведь чтобы ее обновить, нужно, чтобы все самостоятельно обновились через покупку диска, либо, если мы говорим про серверы, админы накатили новую версию.
Разумеется, если ты сейчас будешь выпускать обновления раз в полгода, твой бизнес отправится по направлению нах*й. Отсюда рождаются два основных принципа:
👉 команда разработки должна участвовать в развертывании;
👉 наша кодовая база должна быть готова к развертыванию в любой момент времени.
Уже из этих принципов мы получаем подходы к работе с Git (православный trunk-based, а не загнивающий Git Flow), Docker, чтобы синхронизировать окружение разработки и развертывания, Kubernetes, чтобы он сам убрал старые инстансы и поднял новые, и все прочее, что относится к DevOps.
Continuous Integration — постоянная интеграция. Возникает вопрос: интеграция чего во что? Мы все работаем с кодом и, вероятнее всего, работаем в какой-то команде. Когда мы делаем какие-то изменения, то должны эти изменения распространить на других участников команды, а также получить изменения от них.
Сейчас для этого повсеместно используется Git. У тебя есть локальная версия кода, изменения в которой ты отправляешь на удаленный сервер. Другими словами, ты "интегрируешь" свои изменения с изменениями других участников.
Понимаете суть? Если у тебя настроен Git и есть практика условно раз в день отправлять свои изменения и получать изменения от остальных членов команды, у тебя уже в некотором смысле есть CI.
Вокруг этой идеи затем строится процесс, чтобы правильно внедрить наши изменения: хорошо бы их сначала проверить — прогнать линтер, прогнать тесты, сделать сборку. Ну и еще перед интеграцией наших изменений, чтобы наша команда эти изменения просмотрела, отсюда мы получаем код-ревью.
Continuous Delivery — постоянное развертывание. Этот принцип уже исходит из следующей проблемы. Вот есть разработка, которая пишет код, создает систему. И есть команда, отвечающая за развертывание. Проблема в коммуникации между этими двумя группами: одна группа жалуется на "тупых админов", вторая — на "криворуких разработчиков".
Помимо этого, софт раньше поставлялся четкими версиями. Вот выпустили вы ПО версии 2, и все, ближайшие пару лет будете на ней сидеть. Ведь чтобы ее обновить, нужно, чтобы все самостоятельно обновились через покупку диска, либо, если мы говорим про серверы, админы накатили новую версию.
Разумеется, если ты сейчас будешь выпускать обновления раз в полгода, твой бизнес отправится по направлению нах*й. Отсюда рождаются два основных принципа:
👉 команда разработки должна участвовать в развертывании;
👉 наша кодовая база должна быть готова к развертыванию в любой момент времени.
Уже из этих принципов мы получаем подходы к работе с Git (православный trunk-based, а не загнивающий Git Flow), Docker, чтобы синхронизировать окружение разработки и развертывания, Kubernetes, чтобы он сам убрал старые инстансы и поднял новые, и все прочее, что относится к DevOps.
👍43❤9
Итак, на самом деле у меня сегодня день рождения. Я бы не стал об этом писать, потому что в целом для меня это не то чтобы особенный день. Ну да, чуть повышенное внимание, конечно, приятно, не буду скрывать, но все же, день как день.
Однако произошла прикольная штука. Ровно 5 лет назад я пытался написать диплом для магистратуры. Диплом был по теме, связанной со сверточными нейронными сетями. ChatGPT тогда не было, и реализацию я, разумеется, просто спиздил у более умного друга, но это не важно.
Я жутко прокрастинировал написание диплома, но писать все равно хотелось. Поэтому я написал письмо самому себе через пять лет, то есть в будущее.
Просто хотел поделиться некоторыми строками из него, чтобы похихикать вместе.
Ну, если, пройтись по всему письму, много чего я так и не успел сделать. Гребаные 120 кг, в этом году я их точно пожму! При этом многое сделал того, что не планировал, например, этот канал.
Тут должно быть какое-то пафосное заключение, но размер моего мозга по-прежнему конкурирует с орехом, поэтому просто лайк поставьте, и продолжим про CI говорить.
Однако произошла прикольная штука. Ровно 5 лет назад я пытался написать диплом для магистратуры. Диплом был по теме, связанной со сверточными нейронными сетями. ChatGPT тогда не было, и реализацию я, разумеется, просто спиздил у более умного друга, но это не важно.
Я жутко прокрастинировал написание диплома, но писать все равно хотелось. Поэтому я написал письмо самому себе через пять лет, то есть в будущее.
Просто хотел поделиться некоторыми строками из него, чтобы похихикать вместе.
Ну, если, пройтись по всему письму, много чего я так и не успел сделать. Гребаные 120 кг, в этом году я их точно пожму! При этом многое сделал того, что не планировал, например, этот канал.
Тут должно быть какое-то пафосное заключение, но размер моего мозга по-прежнему конкурирует с орехом, поэтому просто лайк поставьте, и продолжим про CI говорить.
👍87❤23🔥17🥰3🤔3😁1
Итак, погнали, что такое пайплайн и из чего состоит.
В разных CI системах эта сущность называется по-разному: пайплайн, build chain, workflow. Суть у всех одна, поэтому я буду использовать термин "пайплайн". Любой пайплайн состоит из трех базовых вещей:
👉 триггер – который запускает пайплайн
👉 job (он же Action, он же Build) – части пайплайна, в которых происходит работа, об этом позже
👉 связи между job – в какой последовательности запускать job, кто кого должен ждать
Триггер – отвечает за то, при каком событии стартует пайплайн. Разнообразие зависит от конкретной системы, но чаще всего триггеры привязаны к событиям в Git. CI система следит за изменениями в git и запускает пайплайны на разные события: пуш ветки, мерж ветки, пуш тега. Есть события на абстракции поверх git, например, создание мерж-реквеста. Помимо этого есть шедулинг (запуск в определенное время), ручной запуск по кнопке, запуск по API и всякие вебхуки, которые позволяют подключать сторонние системы.
Job – атомарная единица пайплайна, в которой и происходит работа. В 99% случаев это просто запуск какого-то скрипта в нужном окружении. Саму по себе Job можно представить как функцию. Есть данные на вход, есть данные на выход. Job может быть без сайд-эффектов, а может что-то изменять вовне, например, отправлять сборку в сторы или пушить докер-образ.
Связи между Job. Решил выделить в отдельный пункт, потому что это довольно важная часть, от этого зависит нагрузка на инфраструктуру. Связи позволяют задать зависимости между Job, указать, нужно ли скачивать артифакты от предыдущей Job и что делать, если предыдущая Job упала.
Если собрать все это вместе, то получаем, что сам по себе пайплайн — это просто коллекция job, которые среагировали на какой-то триггер, выстроились в нужный порядок и были запущены в едином контексте.
В разных CI системах эта сущность называется по-разному: пайплайн, build chain, workflow. Суть у всех одна, поэтому я буду использовать термин "пайплайн". Любой пайплайн состоит из трех базовых вещей:
👉 триггер – который запускает пайплайн
👉 job (он же Action, он же Build) – части пайплайна, в которых происходит работа, об этом позже
👉 связи между job – в какой последовательности запускать job, кто кого должен ждать
Триггер – отвечает за то, при каком событии стартует пайплайн. Разнообразие зависит от конкретной системы, но чаще всего триггеры привязаны к событиям в Git. CI система следит за изменениями в git и запускает пайплайны на разные события: пуш ветки, мерж ветки, пуш тега. Есть события на абстракции поверх git, например, создание мерж-реквеста. Помимо этого есть шедулинг (запуск в определенное время), ручной запуск по кнопке, запуск по API и всякие вебхуки, которые позволяют подключать сторонние системы.
Job – атомарная единица пайплайна, в которой и происходит работа. В 99% случаев это просто запуск какого-то скрипта в нужном окружении. Саму по себе Job можно представить как функцию. Есть данные на вход, есть данные на выход. Job может быть без сайд-эффектов, а может что-то изменять вовне, например, отправлять сборку в сторы или пушить докер-образ.
Связи между Job. Решил выделить в отдельный пункт, потому что это довольно важная часть, от этого зависит нагрузка на инфраструктуру. Связи позволяют задать зависимости между Job, указать, нужно ли скачивать артифакты от предыдущей Job и что делать, если предыдущая Job упала.
Если собрать все это вместе, то получаем, что сам по себе пайплайн — это просто коллекция job, которые среагировали на какой-то триггер, выстроились в нужный порядок и были запущены в едином контексте.
👍61🔥14❤2🥰1
Итак, «Любовь, смерть и роботы», 4-й сезон
У Netflix есть интересная тенденция в отношении этого произведения: все чётные сезоны получаются ну очень сомнительными.
Первый сезон – просто идеальный для всех техногиков и любителей фантастики. Каждая серия – настоящее произведение искусства, каждая серия удивляля. Было сложно предсказать, чем всё закончится. Чего только стоит эпизод про йогурт, который захватил мир!
Во втором сезоне авторы ушли в сторону отсылок к другим произведениям: «Терминатор», «Хроники Риддика», «Гаттака», «О дивный новый мир». Ещё добавили троллинг медиа – серия с великаном которая показывает, как быстро мы забываем о крупных новостях. Если в первом сезоне каждая серия удивляла, то во втором создаётся ощущение, что всё это ты уже где-то видел. Из-за этого многие бросили сериал именно на втором сезоне. Среди моих знакомых для многих стало новостью, что третий сезон уже давно вышел.
Третий сезон очень напоминает первый. Создатели, видимо, прислушались к отзывам на второй сезон и просто сделали хорошие, уникальные истории. Вернули трёх роботов, которые всем так полюбились. Поэтому, если вдруг вы его не смотрели – третий сезон крайне рекомендую.
Недавно вышел четвёртый сезон, и он сука странный. Если во втором сезоне ощущалась вторичность, то здесь кажется, что все сюжеты писала нейросеть. В предыдущих сезонах каждая серия была полноценной историей: с началом, развитием и концовкой. А в четвёртом сезоне как будто есть только начало. Мне понравилась только одна серия, тогда как даже во втором, очень сомнительном, мне понравились как минимум две.
Короче, надеюсь, у сериала будут хорошие просмотры, и они всё-таки сделают пятый сезон. Если я хорош в экстраполяции, он должен быть топ.
У Netflix есть интересная тенденция в отношении этого произведения: все чётные сезоны получаются ну очень сомнительными.
Первый сезон – просто идеальный для всех техногиков и любителей фантастики. Каждая серия – настоящее произведение искусства, каждая серия удивляля. Было сложно предсказать, чем всё закончится. Чего только стоит эпизод про йогурт, который захватил мир!
Во втором сезоне авторы ушли в сторону отсылок к другим произведениям: «Терминатор», «Хроники Риддика», «Гаттака», «О дивный новый мир». Ещё добавили троллинг медиа – серия с великаном которая показывает, как быстро мы забываем о крупных новостях. Если в первом сезоне каждая серия удивляла, то во втором создаётся ощущение, что всё это ты уже где-то видел. Из-за этого многие бросили сериал именно на втором сезоне. Среди моих знакомых для многих стало новостью, что третий сезон уже давно вышел.
Третий сезон очень напоминает первый. Создатели, видимо, прислушались к отзывам на второй сезон и просто сделали хорошие, уникальные истории. Вернули трёх роботов, которые всем так полюбились. Поэтому, если вдруг вы его не смотрели – третий сезон крайне рекомендую.
Недавно вышел четвёртый сезон, и он сука странный. Если во втором сезоне ощущалась вторичность, то здесь кажется, что все сюжеты писала нейросеть. В предыдущих сезонах каждая серия была полноценной историей: с началом, развитием и концовкой. А в четвёртом сезоне как будто есть только начало. Мне понравилась только одна серия, тогда как даже во втором, очень сомнительном, мне понравились как минимум две.
Короче, надеюсь, у сериала будут хорошие просмотры, и они всё-таки сделают пятый сезон. Если я хорош в экстраполяции, он должен быть топ.
❤27👎1🥰1
Dev Easy Notes pinned «По многочисленным заявкам (одной) я решил сделать серию постов про то, с чем в основном работаю последние несколько лет, а именно про CI/CD. Расскажу в целом про базу для тех, кто вообще это не трогал: 👉 Что такое пайплайн из чего состоит 👉 Как запускаются…»
Как запускаются пайплайны и где выполняются
В предыдущем посте я уже по сути описал, как запускаются пайплайны: в каждой job указывается триггер, когда он срабатывает, все job собираются в кучу, выстраиваются в порядок и погнали.
Где выполняются пайплайны, а точнее сами job?
Чтобы ответить на этот вопрос, нужно накинуть немного контекста. Вот у нас есть сервер с CI, он рисует web-интерфейс, следит за git, отвечает за функционал создания МРов, запускает и создает пайплайны — всё такое. На этот сервер выделены какие-то ресурсы, т.е. он крутится на какой-то машине. И очень важно, чтобы сервер с CI был подобен алкашу в 21:59 – максимально быстрым.
Возвращаемся к Job. Для выполнения Job нужно определенное окружение. Если мы собираем Android-приложение, нужно, чтобы там, где выполняется Job со сборкой, была установлена JDK, а еще Android SDK, ну и желательно уже скачанный Gradle, чтобы не скачивать каждый раз. Помимо этого, сборка больших приложений — это очень дорого по памяти, нужно, чтобы её было много.
Если у нас более-менее большая команда, то будет создаваться много МРов. И вместе с этим будет запущено большое количество Job. Нам важно, чтобы сервер с CI не тормозил, и при этом чтобы сборкам хватало памяти и процессора. Для этого мы выполнение самих Job выносим на другие машины.
Выглядит это так: мы берем какой-то сервер, устанавливаем на него специальное ПО, которое называется Runner (он же агент в TeamCity). Всё, что делает этот Runner — коннектится к серверу CI как к материнскому кораблю и ждет команды. Когда CI нужно запустить какой-то пайплайн, она помещает список Job в очередь. Runner'ы, которые сейчас не заняты, забирают задачи из этой очереди и начинают выполнять Job.
Очень красивая система, которая позволяет масштабировать нашу инфраструктуру горизонтально. Поэтому даже если у нас будет создано огромное количество пайплайнов, это никак не повлияет на сервер CI. И мы можем в зависимости от нагрузки добавлять или убирать лишние Runner'ы. При этом мы еще и решаем проблему того, что например iOS приложение очень желательно собирать на Mac, а не linux машинах.
Осталась только проблема с окружением, и решается она крайне просто. У нас есть готовый Docker-образ с JDK, Android SDK и всем, что нам нужно для сборки. Когда Runner начинает выполнять Job, он сначала скачивает нужный образ (какой образ использовать, мы указываем в самой Job) и затем запускает нужные скрипты уже в рамках этого образа.
В предыдущем посте я уже по сути описал, как запускаются пайплайны: в каждой job указывается триггер, когда он срабатывает, все job собираются в кучу, выстраиваются в порядок и погнали.
Где выполняются пайплайны, а точнее сами job?
Чтобы ответить на этот вопрос, нужно накинуть немного контекста. Вот у нас есть сервер с CI, он рисует web-интерфейс, следит за git, отвечает за функционал создания МРов, запускает и создает пайплайны — всё такое. На этот сервер выделены какие-то ресурсы, т.е. он крутится на какой-то машине. И очень важно, чтобы сервер с CI был подобен алкашу в 21:59 – максимально быстрым.
Возвращаемся к Job. Для выполнения Job нужно определенное окружение. Если мы собираем Android-приложение, нужно, чтобы там, где выполняется Job со сборкой, была установлена JDK, а еще Android SDK, ну и желательно уже скачанный Gradle, чтобы не скачивать каждый раз. Помимо этого, сборка больших приложений — это очень дорого по памяти, нужно, чтобы её было много.
Если у нас более-менее большая команда, то будет создаваться много МРов. И вместе с этим будет запущено большое количество Job. Нам важно, чтобы сервер с CI не тормозил, и при этом чтобы сборкам хватало памяти и процессора. Для этого мы выполнение самих Job выносим на другие машины.
Выглядит это так: мы берем какой-то сервер, устанавливаем на него специальное ПО, которое называется Runner (он же агент в TeamCity). Всё, что делает этот Runner — коннектится к серверу CI как к материнскому кораблю и ждет команды. Когда CI нужно запустить какой-то пайплайн, она помещает список Job в очередь. Runner'ы, которые сейчас не заняты, забирают задачи из этой очереди и начинают выполнять Job.
Очень красивая система, которая позволяет масштабировать нашу инфраструктуру горизонтально. Поэтому даже если у нас будет создано огромное количество пайплайнов, это никак не повлияет на сервер CI. И мы можем в зависимости от нагрузки добавлять или убирать лишние Runner'ы. При этом мы еще и решаем проблему того, что например iOS приложение очень желательно собирать на Mac, а не linux машинах.
Осталась только проблема с окружением, и решается она крайне просто. У нас есть готовый Docker-образ с JDK, Android SDK и всем, что нам нужно для сборки. Когда Runner начинает выполнять Job, он сначала скачивает нужный образ (какой образ использовать, мы указываем в самой Job) и затем запускает нужные скрипты уже в рамках этого образа.
🔥32👏6❤5😁3🥰1
Ребятки, а поделитесь плиз в коментах, кто и как использует LLM в работе. Есть ли какие best practice, какой агент сейчас в топе и все такое? Интересен ваш опыт.
😁2🔥1
Что такое self-hosted runner?
Если вы пытались настроить GitHub Actions, то могли заметить, что там не нужно настраивать никакие Runner'ы. GitHub для опенсорс-проектов предоставляет какое-то количество бесплатных Runner с бюджетом по времени исполнения.
Другими словами, GitHub уже на своих серверах настроил Runner'ы и предоставляет вам доступ к ним. Это прекрасно работает на опенсорсных проектах или стартапах. Однако с ростом команды и компании у вас уже будут появляться ограничения.
Рано или поздно у вас в Job будут учавствовать какие-то закрытые API, которые вы не хотите открывать вне VPN. В этом случае вам помогут self-hosted runner. Вы разворачиваете ПО Runner'а на своих серверах, у которых есть доступ к внутреннему API, а весь менеджмент пайплайнов остается на серверах GitHub. Это удобно, потому как вам не нужно самим тратить время на поддержку всей CI системы, а только несколько серверов с Runner'ми.
Если же у вас в компании используется Gitlab на своих серверах, то очень вероятно, что у вас по умолчанию все Runner будут self-hosted.
Если вы пытались настроить GitHub Actions, то могли заметить, что там не нужно настраивать никакие Runner'ы. GitHub для опенсорс-проектов предоставляет какое-то количество бесплатных Runner с бюджетом по времени исполнения.
Другими словами, GitHub уже на своих серверах настроил Runner'ы и предоставляет вам доступ к ним. Это прекрасно работает на опенсорсных проектах или стартапах. Однако с ростом команды и компании у вас уже будут появляться ограничения.
Рано или поздно у вас в Job будут учавствовать какие-то закрытые API, которые вы не хотите открывать вне VPN. В этом случае вам помогут self-hosted runner. Вы разворачиваете ПО Runner'а на своих серверах, у которых есть доступ к внутреннему API, а весь менеджмент пайплайнов остается на серверах GitHub. Это удобно, потому как вам не нужно самим тратить время на поддержку всей CI системы, а только несколько серверов с Runner'ми.
Если же у вас в компании используется Gitlab на своих серверах, то очень вероятно, что у вас по умолчанию все Runner будут self-hosted.
👍23❤4🔥3
Как артефакты передаются между job
Как я упоминал в прошлых постах, Job можно представить как функцию: есть входные и выходные данные. Существует два типа данных, которые могут быть как входными, так и выходными аргументами:
👉 Переменные окружения
👉 Артефакты
Как вы помните все Job исполняются Runner'ом. Поэтому перед началом исполнения Job, нужно эти данные передать в сам Runner.
Переменные окружения представляют собой HashMap на уровне всей операционной системы, к которым можно обратиться из любой программы. В контексте CI они могут использоваться, например, для хранения номера билда. В первой Job генерируется какое-то число, которое затем передается через переменные окружения в другие Job. Кроме того, CI-системы добавляют множество своих переменных, чтобы определить, на какой ветке выполняется Job, а также токены для API и другие данные.
Переменные окружения почти ничего не весят и передаются в Runner через CI-сервер, когда он получает задание. Здесь нет ничего интересного.
Артефакты уже куда более интереснее, так как артефактами могут быть любые файлы и папки, удовлетворящие ограничениям по размеру. Самый распространенный пример — это сборка. Одна Job собирает приложение, вторая Job деплоит его или отправляет в магазин приложений. Передать артефакт через CI так же просто, как с переменными окружения, уже не получится. Артефакты могут достигать гигабайтов, и часто одна Job создает артефакт, который нужен в нескольких других Job. Если гонять эти данные через CI-сервер, скорость его работы будет конкурировать с парализованной бабкой.
Следовательно, необходим третий компонент системы, который будет выполнять роль хранения артефактов. Этим компонентом является S3-совместимое хранилище. Job генерирует артефакт, затем все файлы упаковываются в архив и отправляются в S3. Отправленные файлы будут доступны только тем Job, у которых совпадает ID пайплайна. Это гарантирует, что в Job не попадет артефакт из другого пайплайна. Другие Job, которым нужен этот артефакт, просто скачивают его из S3 напрямую, минуя CI-сервер.
Как и с Runner, мы можем улучшать хранилище, масштабируя его горизонтально, и независимо от размера файлов это не повлияет на работу CI-сервера.
Как я упоминал в прошлых постах, Job можно представить как функцию: есть входные и выходные данные. Существует два типа данных, которые могут быть как входными, так и выходными аргументами:
👉 Переменные окружения
👉 Артефакты
Как вы помните все Job исполняются Runner'ом. Поэтому перед началом исполнения Job, нужно эти данные передать в сам Runner.
Переменные окружения представляют собой HashMap на уровне всей операционной системы, к которым можно обратиться из любой программы. В контексте CI они могут использоваться, например, для хранения номера билда. В первой Job генерируется какое-то число, которое затем передается через переменные окружения в другие Job. Кроме того, CI-системы добавляют множество своих переменных, чтобы определить, на какой ветке выполняется Job, а также токены для API и другие данные.
Переменные окружения почти ничего не весят и передаются в Runner через CI-сервер, когда он получает задание. Здесь нет ничего интересного.
Артефакты уже куда более интереснее, так как артефактами могут быть любые файлы и папки, удовлетворящие ограничениям по размеру. Самый распространенный пример — это сборка. Одна Job собирает приложение, вторая Job деплоит его или отправляет в магазин приложений. Передать артефакт через CI так же просто, как с переменными окружения, уже не получится. Артефакты могут достигать гигабайтов, и часто одна Job создает артефакт, который нужен в нескольких других Job. Если гонять эти данные через CI-сервер, скорость его работы будет конкурировать с парализованной бабкой.
Следовательно, необходим третий компонент системы, который будет выполнять роль хранения артефактов. Этим компонентом является S3-совместимое хранилище. Job генерирует артефакт, затем все файлы упаковываются в архив и отправляются в S3. Отправленные файлы будут доступны только тем Job, у которых совпадает ID пайплайна. Это гарантирует, что в Job не попадет артефакт из другого пайплайна. Другие Job, которым нужен этот артефакт, просто скачивают его из S3 напрямую, минуя CI-сервер.
Как и с Runner, мы можем улучшать хранилище, масштабируя его горизонтально, и независимо от размера файлов это не повлияет на работу CI-сервера.
🔥26❤1🥰1😁1
Как работают UI-тесты на CI
Сразу обозначу: тема UI-тестов — это глубокая нора, и я сейчас буду говорить о ней только в контексте CI. Помимо этого, я не работал с UI-тестами на фронте, но, как мне кажется, там используется похожий принцип.
Допустим, у нас есть приложение на Android и iOS, и нам нужно организовать UI-тестирование на CI. Для Android необходимо запустить эмулятор, для iOS — симулятор.
Для Android мы берём базовый Docker-образ, например с Ubuntu, накатываем на него Android SDK и эмулятор. После этого мы можем использовать этот контейнер прямо в CI-джобе и запускать тесты.
Для iOS всё то же самое, но с одной оговоркой: из-за особенностей экосистемы Apple мы обязаны использовать Mac в качестве Runner-а. В нём уже должен быть предустановлен симулятор — никакой Docker тут не поможет.
На этом можно было бы и остановиться: такой подход будет работать, если у вас немного тестов и вы не психопаты, которые в UI-тестах ходят в реальный бэк. Но что делать, если у нас, скажем, 10 тысяч UI-тестов?
👉 Во-первых, одной джобой тут явно не обойтись.
👉 Во-вторых, если выполнять тесты последовательно на одном эмуляторе — вам никакого времени не хватит.
Именно поэтому почти в каждой крупной компании делают свою ферму устройств. Берём кластер серверов (кто-то хотел про кубер, вот тут он и выходит на сцену) и поднимаем множество контейнеров с Android-эмуляторами. Для iOS — используем кластер Mac-машин и на них запускаем симуляторы. Кроме того, можно подключить реальные устройства к сети и использовать уже их для тестов.
Теперь на CI-runner-е нам не нужно накатывать тяжёлый эмулятор. Мы просто разбиваем все наши тесты на группы. Каждая группа отправляется на свой эмулятор (или реальное устройство). После выполнения всех тестов мы собираем результаты со всех устройств, агрегируем их и формируем финальный отчёт.
Всю эту возню с разбивкой тестов, запуском, сбором результатов и т.д. берёт на себя специальный инструмент — Test Runner. Не путайте его с CI-runner-ом или JUnit Runner-ом — это совсем другое, про это писал тут.
В итоге в мобильной инфре мы получаем эдакий фрактал. Мы можем масштабировать как CI-runner-ы (чтобы обрабатывать больше джоб), так и количество устройств в ферме (чтобы джоба с тестами прогонялась значительно быстрее). Помимо этого мы можем идти и дальше, например разбивать все тесты на несколько CI-Job, каждая их которых будет использовать по 20-30 эмуляторов.
Сразу обозначу: тема UI-тестов — это глубокая нора, и я сейчас буду говорить о ней только в контексте CI. Помимо этого, я не работал с UI-тестами на фронте, но, как мне кажется, там используется похожий принцип.
Допустим, у нас есть приложение на Android и iOS, и нам нужно организовать UI-тестирование на CI. Для Android необходимо запустить эмулятор, для iOS — симулятор.
Для Android мы берём базовый Docker-образ, например с Ubuntu, накатываем на него Android SDK и эмулятор. После этого мы можем использовать этот контейнер прямо в CI-джобе и запускать тесты.
Для iOS всё то же самое, но с одной оговоркой: из-за особенностей экосистемы Apple мы обязаны использовать Mac в качестве Runner-а. В нём уже должен быть предустановлен симулятор — никакой Docker тут не поможет.
На этом можно было бы и остановиться: такой подход будет работать, если у вас немного тестов и вы не психопаты, которые в UI-тестах ходят в реальный бэк. Но что делать, если у нас, скажем, 10 тысяч UI-тестов?
👉 Во-первых, одной джобой тут явно не обойтись.
👉 Во-вторых, если выполнять тесты последовательно на одном эмуляторе — вам никакого времени не хватит.
Именно поэтому почти в каждой крупной компании делают свою ферму устройств. Берём кластер серверов (кто-то хотел про кубер, вот тут он и выходит на сцену) и поднимаем множество контейнеров с Android-эмуляторами. Для iOS — используем кластер Mac-машин и на них запускаем симуляторы. Кроме того, можно подключить реальные устройства к сети и использовать уже их для тестов.
Теперь на CI-runner-е нам не нужно накатывать тяжёлый эмулятор. Мы просто разбиваем все наши тесты на группы. Каждая группа отправляется на свой эмулятор (или реальное устройство). После выполнения всех тестов мы собираем результаты со всех устройств, агрегируем их и формируем финальный отчёт.
Всю эту возню с разбивкой тестов, запуском, сбором результатов и т.д. берёт на себя специальный инструмент — Test Runner. Не путайте его с CI-runner-ом или JUnit Runner-ом — это совсем другое, про это писал тут.
В итоге в мобильной инфре мы получаем эдакий фрактал. Мы можем масштабировать как CI-runner-ы (чтобы обрабатывать больше джоб), так и количество устройств в ферме (чтобы джоба с тестами прогонялась значительно быстрее). Помимо этого мы можем идти и дальше, например разбивать все тесты на несколько CI-Job, каждая их которых будет использовать по 20-30 эмуляторов.
👍10🔥3❤1🥰1
Подарили мне на ДР вот такую картину, и я подумал: у меня же авторский канал, я делаю посты только про разработку — нужно иногда разбавлять чем-то ещё.
Поэтому сделаю вид, что вам не похуй, и черкану пару предложений про мою любимую игру от FromSoftware.
Для тех, кто вообще не в теме: значит, есть такая японская компания. Делает она игры, скажем так, специфичные — для определённого круга геймеров с мазохистскими наклонностями. В основном это игры в стиле дарк-фэнтези и жанре RPG. Игры, в которых только тлен, депрессия и безнадёга — прям как в разработке плагинов под Gradle.
Игры от фромов мало того, что сложные геймплейно (тебя хочет убить всё, что движется, а если умираешь — беги с последнего костра), так ещё и сюжет подаётся не через кат-сцены, как обычно, а через записки, описания предметов, диалоги... Короче, нужно нехило так усилий приложить, чтобы понять, что вообще тут происходит. Да, прям как в моей любимой системе сборки.
Магнум опус компании FromSoftware — это серия Dark Souls, про которую хотя бы краем уха слышал каждый.
И вот, в 2019 выходит Sekiro — от тех же фромов. До сих пор многие ошибочно считают, что Sekiro — это Dark Souls, только в Японии. Но Sekiro вообще ничего общего не имеет с Dark Souls.
Ну и, короче, теперь кратко — почему она мне нравится.
Sekiro — одна из тех игр, в которых практически нет прокачки персонажа. У вас одно оружие на всю игру, максимум, что можно поменять — это протез (и то опционально). Нет никакой брони и характеристик персонажа.
Обычно как бывает: есть персонаж в игре, которого вы прокачиваете. Он становится сильнее — и это позволяет вам продвигаться дальше, даже если вы сами особо не меняетесь. В Sekiro же единственный способ пройти дальше — это самому стать лучше. Это подкупает: враги становятся сильнее, а персонаж почти не меняется, и ты понимаешь, что именно ты становишься лучше, а не герой на экране.
Ну и ещё пара крутых моментов:
👉 В ней есть адекватный сюжет, который подаётся через кат-сцены.
👉 Есть механика воскрешения, которая реально спасает и делает геймплей чуть проще.
👉 Финальный босс — для меня лучший босс не только в Sekiro, а, наверное, вообще в играх. Он элегантен, он крут, его невозможно пройти один раз — вам почти наверняка захочется пережить это сражение снова. Битва с ним не похожа на бой с боссом, она больше напоминает завораживающий танец (во время которого тебя раз пять на копьё насадят).
Если вам не заходит серия Dark Souls, на Sekiro точно стоит обратить внимание. Это совсем другая игра, которая на самом деле в разы проще того же Dark Souls.
Поэтому сделаю вид, что вам не похуй, и черкану пару предложений про мою любимую игру от FromSoftware.
Для тех, кто вообще не в теме: значит, есть такая японская компания. Делает она игры, скажем так, специфичные — для определённого круга геймеров с мазохистскими наклонностями. В основном это игры в стиле дарк-фэнтези и жанре RPG. Игры, в которых только тлен, депрессия и безнадёга — прям как в разработке плагинов под Gradle.
Игры от фромов мало того, что сложные геймплейно (тебя хочет убить всё, что движется, а если умираешь — беги с последнего костра), так ещё и сюжет подаётся не через кат-сцены, как обычно, а через записки, описания предметов, диалоги... Короче, нужно нехило так усилий приложить, чтобы понять, что вообще тут происходит. Да, прям как в моей любимой системе сборки.
Магнум опус компании FromSoftware — это серия Dark Souls, про которую хотя бы краем уха слышал каждый.
И вот, в 2019 выходит Sekiro — от тех же фромов. До сих пор многие ошибочно считают, что Sekiro — это Dark Souls, только в Японии. Но Sekiro вообще ничего общего не имеет с Dark Souls.
Ну и, короче, теперь кратко — почему она мне нравится.
Sekiro — одна из тех игр, в которых практически нет прокачки персонажа. У вас одно оружие на всю игру, максимум, что можно поменять — это протез (и то опционально). Нет никакой брони и характеристик персонажа.
Обычно как бывает: есть персонаж в игре, которого вы прокачиваете. Он становится сильнее — и это позволяет вам продвигаться дальше, даже если вы сами особо не меняетесь. В Sekiro же единственный способ пройти дальше — это самому стать лучше. Это подкупает: враги становятся сильнее, а персонаж почти не меняется, и ты понимаешь, что именно ты становишься лучше, а не герой на экране.
Ну и ещё пара крутых моментов:
👉 В ней есть адекватный сюжет, который подаётся через кат-сцены.
👉 Есть механика воскрешения, которая реально спасает и делает геймплей чуть проще.
👉 Финальный босс — для меня лучший босс не только в Sekiro, а, наверное, вообще в играх. Он элегантен, он крут, его невозможно пройти один раз — вам почти наверняка захочется пережить это сражение снова. Битва с ним не похожа на бой с боссом, она больше напоминает завораживающий танец (во время которого тебя раз пять на копьё насадят).
Если вам не заходит серия Dark Souls, на Sekiro точно стоит обратить внимание. Это совсем другая игра, которая на самом деле в разы проще того же Dark Souls.
❤34😁7🗿4👍2👎1🔥1
Я последнее время в своих постах все дальше ухожу от тем мобильной разработки. Даже про kotlin давно ничего не упоминал, начинаю забывать свои корни. Если же вы сильно соскучились по постам про Kotlin, то рекомендую канал Kotlin Adept Notes. Название канала даже созвучно с моим, но это чистое совпадение.
Список постов, которые на мой вкус достойны вашего внимания:
👉 Что за Kotlin UUID?
👉 Сравнение реализации компонента Compose и SwiftUI
👉 Android Lint vs Detekt
Ну и мое любимое, это история про первое мобильное приложение
Список постов, которые на мой вкус достойны вашего внимания:
👉 Что за Kotlin UUID?
👉 Сравнение реализации компонента Compose и SwiftUI
👉 Android Lint vs Detekt
Ну и мое любимое, это история про первое мобильное приложение
Telegram
Kotlin Adept Notes
Канал о разработке на Kotlin и обо всем, что с ним связано
По всем вопросам и рекламе: @ajiekcx
По всем вопросам и рекламе: @ajiekcx
❤13🤡3🔥1😁1