Обновить
16K+
51
Растегаев Юрий@rurikovich

ТехЛид с менеджерской субличностью

20,1
Рейтинг
19
Подписчики
Хабр КарьераХабр Карьера
Отправить сообщение

Scala 3.8: три вещи, которые сломают ваш проект при апгрейде

Scala 3.8 вышла в январе 2026. Фич много, но сначала - про то, что может больно ударить при переезде.

1. JDK 17 - жёсткое требование

Никакого JDK 11, никакого JDK 8. Реализация lazy val переписана с sun.misc.Unsafe на VarHandles - потому что в JDK 26 Unsafe будет бросать исключения. Компилятор просто откажется работать на старой JVM.

Если ваша инфраструктура ещё на JDK 11 - апгрейд Scala придётся отложить до апгрейда JVM. Scala 3.3 LTS пока остаётся на JDK 8+.

2. stdlib скомпилирована Scala 3 - и один неочевидный момент

Бинарная совместимость сохранена, но явная передача ClassTag теперь требует using:

// ❌ Перестало компилироваться
Array.empty(reflect.ClassTag.Int)

// ✅
Array.empty(using reflect.ClassTag.Int)
// или просто
Array.empty[Int]

Хорошая новость: компилятор умеет чинить такие места автоматически. Запускаем на Scala 3.7.4 перед апгрейдом:

scalac -source:3.7-migration -rewrite YourFile.scala

3. betterFors меняет тип результата - молча

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

// Этот код даёт РАЗНЫЕ результаты в 3.7 и 3.8
val result: Iterable[(Int, Int)] =
  for
    (k, v) <- Map(1 -> 1, 2 -> 1, 3 -> 1)
    x = k + v
    (a, b) = f(x)
    (y, z) <- Map(42 -> 27)
  yield (a + y, b + z)
// 3.7 → List((43,29), (43,30), (43,31))
// 3.8 → Map(43 -> 31)

В 3.7 синтетический map превращал Map в Iterable. В 3.8 этого шага нет - Map остаётся Map, дубли ключей исчезают. 3.8.2 выдаёт предупреждение на такие места. Не игнорируйте.

Фикс простой - явно приводить к Seq:

(k, v) <- Map(1 -> 1, 2 -> 1, 3 -> 1).toSeq

В своем канале в Telegram и в канале Max о разработке в стартапах рассказываю ещё больше интересного и делюсь опытом, заходите, найдете полезные кейсы!

И ещё одно: не берите 3.8.0 и 3.8.1

Сразу после релиза в 3.8.0 нашли JVM linkage errors при использовании Scala 2.13 библиотек. 3.8.1 закрыл это, но оставил баг в for-comprehension. Стабильная версия — 3.8.2 (вышла 24 февраля 2026).

Обновляться - только на неё.

Теги:
Всего голосов 5: ↑3 и ↓2+1
Комментарии0

Разбираемся как принимать звонки в браузере. Основы WebRTC\SIP\RTP.

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

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

Разберем основную схему организации передачи голоса. Браузер по сути работает как SIP‑телефон: сигнализация через WebSocket, медиа — по RTP.

Упрощенно схему работы WebRTC/SIP можно разделить на "регистрацию", "звонок" и "завершение":
Упрощенно схему работы WebRTC/SIP можно разделить на "регистрацию", "звонок" и "завершение":

1. Регистрация в сети

  • Оператор открывает страницу в браузере.

  • Браузер отправляет SIP REGISTER на SIP‑сервер (WebSocket/TLS).

  • SIP‑сервер отвечает 200 OK.

  • В интерфейсе показывается «Вы в сети» — оператор готов к звонкам.

2. Звонок

  • SIP‑сервер отправляет SIP INVITE в браузер.

  • Браузер показывает уведомление «Входящий».

  • Оператор нажимает «Принять».

  • Браузер запрашивает доступ к микрофону (getUserMedia) — внутреннее действие.

  • Браузер отправляет SIP 200 OK + SDP на SIP‑сервер.

  • SIP‑сервер отправляет SIP ACK в браузер.

  • SIP‑сервер даёт команду RTP/SRTP‑шлюзу установить медиа‑сессию.

  • Медиа (RTP/SRTP по UDP) передаётся между браузером и RTP‑шлюзом.

  • Начинается разговор.

3. Завершение звонка

  • Оператор нажимает «Завершить».

  • Браузер отправляет SIP BYE на SIP‑сервер.

  • SIP‑сервер отвечает 200 OK.

  • Передача RTP/SRTP прекращается.

Если тема будет интересна, то далее обсудим схему работы backend'а и варианты развития общей схемы передачи голоса с плюсами, минусами и ограничениями.

В своем канале в Telegram и канале в Max о разработке в стартапах рассказываю еще больше интересного и делюсь опытом, заходите, буду рад!

Спокойных вам релизов и захватывающих решений !

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Описывайте проблему вместо конкретных рецептов

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

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


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

В своем канале о разработке в стартапах делюсь опытом, заходите, буду рад!

Берегите себя и своих коллег от рецептов, ставьте проблему и не сужайте пространство решений.

Теги:
Всего голосов 7: ↑1 и ↓6-4
Комментарии0

Что с Релизом ?!

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

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

За 15 лет в разработке я участвовал на разных ролях в создании совершенного разного типа продуктов, как по способу запуска(десктоп, веб и тд), типу поставки(desktop, saas, onprem) так и по зрелости продукта(прототип, mvp, плановое развитие зрелого продукта, полное переписывание внутренней системы крупного банка и тд и тп).

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

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

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

Часть, относящаяся к менеджменту релиза также удивляла как ни странно своим отсутствием и незримостью и непрозрачностью для большей части команды разработки.
Все это происходило из за сочетания типа поставки: saas (вернее отсутствия onprem поставки и строгих проверок на стороне клиентов, как говорится "все свое" ) и факта сосредоточения функций релиза в умах 1.5 человек, 0.5 из которых уже давно не относилось к отделу разработки.

Назовем такой тип релиз-менеджмента "one man release managment". Он неплохо работал, пока разработка шла по привычному процессу в рамках небольших изменений логики. Все быстро и удобно. Один человек знает и код и деплой, описывать ничего не надо, планов развертывания строить не надо, планов отката также. И ответственность тоже шарить не надо ;)

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

Всем добра и тихих релизов !

Теги:
Рейтинг0
Комментарии0

5 Ошибок Рефакторинга

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

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

  3. Рефакторить без промежуточных проверок
    Когда вдохновение несет и хочется "прибраться" и тут и там и везде и некогда останавливаться можно "пролететь поворот" и даже не один. Лучше всего делить рефакторинг на логические этапы. "Дешевые" по времени и ресурсу проверки можно и нужно запускать как можно чаще: компиляция, тесты, запуск приложение локально. Между крупными этапами желательно проводить регрессионное тестирование. И самое отличное поэтапный релиз рефакторинга, чтобы провести не только синтетические проверки, но самую важную "проверку продакшеном"

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

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

    В своем канале о разработке в стартапах делюсь опытом и рассказываю еще больше удачных примеров и факапов. Буду рад видеть каждого! Заходите!

    Всем удачного рефакторинга!

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Информация

В рейтинге
429-й
Откуда
Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Архитектор программного обеспечения, Деливери-менеджер
Ведущий
SQL
PostgreSQL
ООП
Java
Scala
DDD
Docker
Linux
Python
Функциональное программирование