AI / Rust / Python

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

В процессе изучения пишу свой pet-проект на github, в котором есть интеграция с OpenAI (ChatGPT) и TTS сервисом. Планирую еще сделать интеграцию с каким нибудь AI для генерации изображений (например dreamstudio.ai).

Так-же пришлось написать маленький срипт на Python с использованием FastAPI и Silero AI для TTS запросов. Бот умеет отвечать голосом, зачитывая ответы с ChatGPT. Для этого пришлось поднять отдельный сервис.

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

Кстати, превью для этой записи, я тоже сгенерировал на dreamstudio.ai

PM2 cluster prometheus exporter

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

Из подручных средств был забикс и графана.

Оказалось что для nodejs есть модуль prom-client который умеет экспортировать метрики, но вот незадача — с pm2 как и другие модули он работать не умеет.

Проблема в том, что метрика собранная в одном процессе, не может нормально получена в другом процессе, который отвечает за http предоставление метрики zabix агенту.

Исправляем упущение: pm2-prom-client

Модуль в принципе для prometheus, но нам он тоже подошел

Вся его суть сводится к передачи по шине pm2 метрик в агентский процесс с последующим экспортом в plain-text либо json

Zero Downtime Deployment / TypeScript

Сегодня поговорим о деплое с нулевым даунтаймом в NodeJs приложении.

Для того что бы это было возможным, ваше приложение должно быть запущено в child process. Например используйте PM2 / ts-node-dev

Итак:

Первое что нам нужно сделать, это сообщить о том, что новый (задеплоенный) процесс готов принимать на себя работу передеплоемого приложения. Для этого необходимо вызвать

process.send(“ready”)

В вашем приложении, после того как все необходимые зависимости перейдут в состояние готовности. Например коннект с базой установится и т.п.

Так же в нашем приложении нужно добавить логику, по завершению всех текущих операций при получении сигнала терминации (SIGINT)

process.on(“SIGINT”, () => {
  this.connection.close(); // Например закроем текущие соединение с AMQP и перестанем принимать новые сообщения
  setTimeout(() => {
    process.exit()
  }, 5000) // Подождем 5 сек пока завершаться текущие процессы
})

Запуская такое приложение, например при помощи ts-node-dev, вы можете заметить что после control+c приложение завершается не сразу, а через 5 минут.

Что произойдет:

  • Новое приложение, запущенное в child process запускается и сообщает ready, после чего начинает бизнес логику
  • одновременно с этим старому процессу посылается SIGINT и оно переходит в режим завершения работы и финализазции, после чего уничтожается.

Пример

class App {
  private isOnline = true

  public start() {
    console.log(“Started”)
    this.restartListener()
    this.loop()
  }

  private loop() {
    if (!this.isOnline) return
    console.log(“Some business logic like redis/sql/amqp and others operation”)
    this.loop()
  }

  private restartListener() {
     if (typeof process.send !== “function”) return

     process.send(“ready”)
     process.on(“SIGINT”, () => {
       this.isOnline = false
       setTimeout(() => {
         process.exit()  
       }, 3000)
     })
  }

}

Года два назад и представить бы не мог

В этом году постоянно ловлю себя на мысли, что происходит то, что я даже совсем недавно и представить не мог:

  • Война России с Украиной сопровождающаяся вероятностью применения ядерного оружия, примитивной и кривой пропагандой с разжиганием межнациональной ненависти. Свобода слова исчезла окончательно, инакомыслие наказывается штрафом и тюремным сроком.
  • Рождение детей и вынужденная эмиграция сначала из Москвы в Сочи (на машине два дня), потом из Сочи в Казахстан вместе с семьей и машиной
  • Раскол мнений в России привел к конфликтам и ссорам, в том числе между близкими людьми.
  • Глобальный кризис в IT сфере. Во многих компаниях-гигантах сокращения доходят до тысячи айтишников.
  • На фоне глобального кризиса и войны многие талантливые разработчики (особенно не семейные) просто отказываются покидать страну (при имеющейся на то возможности) и смиренно ждут, пока их попросят на войну.
  • ChatGPT уже готов потягаться со многими профессионалами. Сейчас он достаточно неплохо пишет код на всех языках по текстовому ТЗ, можешь найти в любом коде уязвимые места и баги а так-же можешь сочинить неплохой текст на любом языке для linkedin.
  • На фоне привлекательных зарплат в IT, за последние пару лет образование поставленно на поток, из IT ушла какая-то субкультурность. Очень большой процент специалистов мотивированно исключительно деньгами.

Некоторые пункты переворачивают сознание:

  • Люди, которые учили нас добру, народному единству, ругали нас за сигареты и драки в школе — поддерживают войну.
  • Попрежнему остаются люди, абстрагированные от происходящего.
  • Среди поддерживающих есть и православные.
  • Израиль бьет по Палестине, что тоже не вызывает особых угнетений у Православного сообщества.
  • Результат многолетней работы человека на позиции менеджера — обнищание населения, запредельный уровень коррупции и третья мировая война. Но люди продолжат повторять «кто если не он?».

Чему я научился в результате этого

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

Обновил колеса у марка. XXR 526 2P

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

Я очень хотел себе SSR Minerva AGLE, но сейчас это очень большая редкость. Поэтому купил что то похожее.

XXR 526 2P. 8,5 ширина у них и 35 вылет. R18. Плюс проставки по 1.2 см

Читать полностью

Те, кто молчал, перестали молчать. Те, кому нечего ждать, садятся в седло

Три года назад я недоумевал почему патриотическое воспитание происходит через милитаризацию: юнармия, концерты с военной тематикой, периодические выставки военной техники. Почему военным такая дешевая ипотека а не ученым? Сегодня же не остается вопросов и курс правительства для меня окончательно ясен.

Мне очень жаль что Россия не имеет своих условных Илонов Масков, Билов Гейтсов, Стивов Джобсов. Очевидно они тут не вырастут в ближайшие 50 лет точно. Агрессия, жажда все отнять у успешного соседа, зависть, хамство, жажда халявы, жажда обмануть ближнего — мне все это не близко и отвратительно.

Уже окончательно ясно, что инновационных разработок, передовые технологии, освоение космоса на моей жизни я уже не увижу в России. Это будут жалкие пародии типо телефонов из китая с операционкой от гугл, и железом из США, пиратство и возможно какие то клоны популярных сервисов, которые всегда будут отставать в технической реализации, будут грязнуть в откатах и распилах.

У меня нет никакого желания принимать участие в компании по импортозамещению покинувших Россию сервисов. Мне хватило уроков, которые я вынес из ситуации с Павлом Дуровым и Вконтакте, Евгением Чичваркиным, и проектом nginx. Я открывал и закрывал ИП, обивал пороги налоговых и роскомнадзора. Все. Хватит, спасибо.

Принял решение в ближайшее время инвестировать в образование и эвакуировать семью и детей. Что бы дети росли свободными, без сумасшедшей цензуры. Что бы они спокойно могли сказать 2*2=4, что бы установка была на созидание а не разрушение.

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

Asterisk, ARI. Коммутируй как Бог

В этой небольшой статье ничего не будет про план нумерации астериска. Речь пойдет про ARI — гибкий интерфейс управления Астериском.

Как только в астериск приходит инвайт, и вызов уходит в нашу программу (Stasis) мы получаем возможность для низкоуровневого построения звонка.

Взаимодействие с ARI происходит через прием событий по websocket от астериска, обработку и создания новых событий через HTTP REST API в сторону ARI.

StasisStart

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

Упрощенная схема обычного звонка

  1. Получили инвайт (StasisStart) событие от ARI, что сигнализирует о созданном канале A
  2. Создали канал B с эндпоинтом в сторону сип пира, либо в локальный прокси. (пример. SIP/MY_PEER/79001231122)
  3. Канал А из п.1 и B из п.2 объядинили в bridge
  4. Сделали дозвон (dial) в канал B
  5. Подождали ARI событие ChannelStateChange для канала B. И в случае если state — ‘Up’, запускаем ответ в канал A и звонок диалог начинается.
  6. При получении события ChannelHangupRequest для канала A либо B разрушаем звонок.

Сессия звонка

Созданных каналов может быть множество и есть необходимость знать, к каким звонкам относятся события по каким каналам. Поэтому при создании каналов в сторону другого абонента, можно записывать в стор для созданного канала указатель на id канала A, а в сторе для канала A хранить все данные, включая CDR и прочую техническую информацию.

В качестве хранилища я бы рекомендовал использовать redis, так как при больших cps и интенсивных запросах в базу данных может образоваться существенная нагрузка на жесткие диски и просесть производительность.

Оптимизация

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

Тест производительности

Для тестирования я использовал консольную утилиту baresip, инициировав баш скриптом 200 дозвонов по пулу тестовых номеров, которые отвечают tt-monkeys.

200 параллельно запущенных звонков сумарно потребили около 5% загрузки на CPU. Все звонки завершились успешно, включая записанные CDR.

Дебаг stasis приложения, которое сигнализирует об отвеченных звонках
SIP сигнализация

Моя экспансия на GameDev #3

Мое третье явление в game dev вышло давольно плодотворным.

Опять моя тоска по закрытому игровому проекту, в котором мы всем кланом боролись с полчищами монстров и в pvp соревнованиях 4×4 и 2×2 одержала верх и я решил попробовать сам написать подобный проект с нуля.

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

Игровой клиент

Для игрового клиента решил использовать движок Unity 3d. При создании рабочего прототипа использовал бесплатные модели, которые находятся в свободном доступе, что бы не сгореть на этапе создания графического дизайна. Хоть у меня за последние три года и появился опыт работы в Blender, но отрисовка 3d моделей отнимает очень много сил. Так что пока из графики мое — только UI.

На этапе альфы планирую:

  • Уровень COOP сражения (до четырех online игроков) с волнами, в которых игроку предстоит с командой зачистить локацию от разнообразных монстров (от летающих до ползающих) плюс босс на последней волне.
  • PVP 1v1 на зеркальной арене.

Сервер

Сервер матча я написал на Nodejs. Для коммуникации клиент-сервер использую вебсокет и json формат. Каждый матч инстанцирует процесс, который на определенном сетевом порту обслуживает игровую сессию для всех игровых клиентов матча. Я пока не определил на сколько это хорошая идея использовать tcp протокол а не udp. Но при тестировании с двух устройств одновременно проблем не возникло.

Сейчас сервер успешно спаунит NPC монстров по сценарию из базы данных на все игровые клиенты.

Большая тема для обсуждения — это синхронизация позиционирования и вообще действий игрока, при потере пакетов. Так как может получиться так что у игрока на клиенте персонаж уже находится в точке C, а у всех остальных (из за потери данных) в точке B.

Ассеты

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

Git репозиторий

Игра включает в себя код сервера и клиента. Если с сервером при хранении все просто, так как код занимает 4 мегабайта, то с клиентом сложнее. Сырые текстуры для пребилда занимают около гигабайта и будут рости. Поэтому я решил собрать дома свой гит сервер на raspberry pi 4.

Приобрел raspberry pi 4, а так-же корпус к нему, куллер и ssd на m2 сокете на 512GB и сливаю весь код локально на raspberry.

raspberry pi 4 в корпусе m2 Argon выглядит как тв приставка

Ссылка на корпус и ssd диск https://a.aliexpress.com/_9RbPFU

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

Финал

Мне пришла идея логировать все изменения и наработки по игре в телеграм канал https://t.me/sniperhit так же я завел домен с рабочий названием, где добавил виджет на канал https://sniperhit.ru/. Далее думаю все новости по проекту писать только туда.

Высшая школа бизнеса Стэнфордского университета

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

Эта программа, конечно открывает на многое глаза. Мне повезло! Я смог познакомится с Baba Shiv и другими классными преподавателями из Стэндфорта а так же пообщаться с другими CEO и менеджерами и узнать какие у них возникают проблемы и как они их решают.