Node.JS [ru] | Серверный JavaScript (@we_use_js) — Telegram-канал | Telegram Dialogs
Все каналы
Node.JS [ru] | Серверный JavaScript

Node.JS [ru] | Серверный JavaScript

@we_use_js

11.2K подписчиков технологии

Node.js, backend и AI-разработка: статьи, новости, вайбкодинг, автоматизация и работа с ИИ-агентами. Личный блог автора - @just_genych По вопросам рекламы или разработки: @g_abashkin РКН: https://vk.cc/cJPGOP

Последние публикации

Node.JS [ru] | Серверный JavaScript
17.07.2026 13:07 · 👁 321
⁣Диагностика неявного deadlock в async_hooks при IPC в Node.js кластерах Вы сталкивались с ситуацией, когда кластеризованное Node.js приложение потребляет 100% CPU без видимых ошибок, а event loop замирает? Часто причина — неявный deadlock в async_hooks, возникающий при смешивании синхронных IPC-вызовов через child_process.send и MessagePort.close в воркерах. Гонка за ресурсами IPC send() в child_process синхронно блокируется до отправки данных. Если следом вызвать port.close(), возникает замыкание: send() удерживает IPC-ресурс, close() ждет его освобождения, а async_hooks зависает в состоянии "ожидания завершения". Результат — ресурсы не освобождаются, ошибок нет, CPU занят вхолостую. Production-пример: кластер с обработкой запросов, где каждый воркер отправляет результат через send и закрывает порт. После пары тысяч запросов — deadlock, все воркеры зависают. Диагностика Чтобы отловить проблему, включите логирование async_hooks с таймстампами: - init для IPC-каналов появляется - destroy приходит с задержкой или отсутствует вовсе - No errors in logs Практический совет: исправление Замените синхронный send на асинхронный. Плохой паттерн: send({ data }, (err) => { port.close(); }); Хороший паттерн: await new Promise(resolve => process.send({ data }, resolve)); port.close(); Используйте MessageChannel вместо child_process.send — он избегает блокировки. Если deadlock уже произошел, убивайте воркер через worker.kill(), а не process.exit(). Профилактика - Ставьте timeout на все IPC-операции - Мониторьте async_hooks метрики через performance hooks - Гоняйте кластер под нагрузкой с логированием ресурсов Вывод: Синхронный IPC-вызов с последующим закрытием порта создает неявный deadlock в async_hooks, который проявляется только как 100% CPU и зависший event loop — переходите на асинхронные паттерны для всех межпроцессных коммуникаций.
Node.JS [ru] | Серверный JavaScript
17.07.2026 09:07 · 👁 476
Point0 — очередной фулстек-фреймворк, который уже успели обозвать конкурентом tRPC. Судя по описанию, DX тут реально похож: те же квери и мутации. Но Point0 идет дальше — позволяет объявлять запросы прямо в клиентских файлах вместе с серверной логикой, сам шарит за гидрацию и дегидрацию при SSR, умеет швырять файлы через FormData, выдает стабильные урлы для эндпоинтов и может отдавать серверные компоненты или интерактивные острова. Плюс фреймворк не кладет редактор мордой в стол, когда эндпоинтов становится дофига, и нормально рулит состояниями загрузки. Автор предполагает, что ты уже шаришь за tRPC — так что в статье накидали примеров на нем для сравнения. Читать далее 👉 Node.JS [ru]
Node.JS [ru] | Серверный JavaScript
17.07.2026 06:07 · 👁 507
Как получить оффер в Яндекс, Сбер, МТС и другие крутые компании? На фото ребята из моего комьюнити, где уже больше 220 frontend-разработчиков. Все они успешно устроились в крутые компании и получили офферы от 300 тыс рублей 🫂 👋 Привет, меня зовут Тихон, я действующий Frontend-разработчик и ментор. За руку довожу до оффера в Big Tech и остаюсь рядом на испытательном сроке. В их жизни больше нет бесконечных скучных созвонов, безуспешных откликов на вакансии, странноватых собесов с вопросами словно ты на олимпиаде. И у тебя тоже получится 😎 У меня есть канал, где я: 👉 Показываю, как пройти HR-фильтр и превратить отклики в реальные приглашения 👉 Помогаю найти мотивацию и разбираюсь с убеждениями, которые мешают расти 👉 На примерах показываю, как проходить собеседования, включая техничку 👉 Разбираю резюме и делюсь лайфхаками — например, как аккуратно «пинговать» рекрутеров И регулярно выкладываю полезное: ▪️ Задачи, на которых валятся кандидаты ▪️ Подборка из 100+ каналов с вакансиями для разработчиков ▪️ 100 вопросов, которые помогут тебе на собеседовании ▪️ Чек-лист для проверки своего резюме Подписывайся: https://t.me/+KcX6eD0fuRY3M2Uy Реклама, erid: 2W5zFJKcvZP ИП Галактионов Тихон Витальевич, ИНН 771618975809
Node.JS [ru] | Серверный JavaScript
16.07.2026 17:07 · 👁 621
MinIO, MongoDB, PostgreSQL для хранения 25 лет истории стоимости акций 💾 Когда ты строишь эмулятор для проверки торговой стратегии — 20 акций, 25 лет поминутных данных — выбор хранилища превращается в головную боль архитектурного уровня. Автор раскурил, почему MinIO тут не взлетел, где MongoDB уперлась в потолок, и как PostgreSQL с Pgpool-II и read-репликами срезал время чтения свечи с 40мс до 10мс. Читать далее: https://habr.com/ru/articles/1059062/ 👉 Node.JS [ru]
Node.JS [ru] | Серверный JavaScript
16.07.2026 14:47 · 👁 597
Просто показываем промокод Просто предлагаем съездить отдохнуть со скидкой 5000 рублей от Яндекс Путешествий. Больше ничего от вас не хотим, потому что понимаем, что сил нет. Забронировать #реклама travel.yandex.ru О рекламодателе
Node.JS [ru] | Серверный JavaScript
16.07.2026 13:07 · 👁 518
⁣Неявное зависание Promise.all при отмене AsyncIterator через AbortController Вы используете for await...of с асинхронным генератором и AbortController для отмены. Кажется, всё чисто, но Promise.all зависает намертво. Проблема в том, что вызов abort() вызывает return() генератора, но если внутри остался незавершённый промис (таймер, подписка, поток), он просто висит, и Promise.all никогда не завершится. Как возникает утечка Когда abort() срабатывает внутри for await...of, итератор завершается. Но если в генераторе есть запущенный, но не завершённый setInterval, await на потоке данных или подписка на событие, этот промис остаётся висеть в памяти. Например, генератор каждую секунду отправляет данные, а при abort обработчик завершает итерацию, но не очищает таймер. Promise.all ждёт этот таймер вечно. Диагностика на практике Добавьте в конец return() генератора console.log('return called'). Если return вызывается, а Promise.all не завершается — ищите, какой ресурс утекает. Используйте обёртку с таймаутом: Promise.race([Promise.all(...), AbortSignal.timeout(5000)]). В продакшне это спасёт от вечного ожидания, но не решит корень проблемы. Совет по исправлению Всегда оборачивайте тело асинхронного генератора в try/finally. В finally явно очищайте все ресурсы: удаляйте слушатели, отменяйте таймеры, разрешайте ожидающие промисы. Например, если внутри генератора есть setInterval: async function* gen(signal) { const timer = setInterval(() => {}, 1000); try { while (!signal.aborted) { await new Promise(r => setTimeout(r, 100)); yield data; } } finally { clearInterval(timer); } } Вывод: Каждый yield и await в асинхронном генераторе должен быть гарантированно завершён до конца итерации, иначе return() не прервёт внутренние промисы, что приведёт к невосстанавливаемому зависанию.
Node.JS [ru] | Серверный JavaScript
16.07.2026 09:07 · 👁 600
npm 12, TypeScript 7.0 и Bun на Rust Выкатили npm 12 — install-скрипты теперь выключены по дефолту. Сломов дофига, так что сперва лучше проапгрейдиться до 11.18.0. GitHub Финальный TypeScript 7.0 — на Go и «в 10 раз быстрее». Но полный API пока не докрутили, поэтому многие советуют пока не слезать с 6.0. Bun переехал с Zig на Rust — автор выкатил полный репортаж о том, как портировал рантайм. Кучу инстансов Claude Code припахали, суммарно сожгли ~$165k по API-ценам. Rust-версия станет базой для Bun 1.4, его ждут с часу на час. Jarred Sumner Node.js 26.5.0 — заимпортили текстовые файлы в ES-модулях через import attributes и blob.textStream(). 👉 Node.JS [ru]
Node.JS [ru] | Серверный JavaScript
16.07.2026 07:48 · 👁 612
Бесплатный курс: веб-дизайн, графика, интерфейсы Получи востребованные навыки: - создание дизайна сайтов и приложений - создание инфографики и карточек для маркетплейсов - работа в графическом редакторе Figma и др. Студенты курса в среднем зарабатывают от 68 000 ₽ уже во время обучения💰 Зарегистрироваться #реклама 16+ ydaev.ru О рекламодателе
Node.JS [ru] | Серверный JavaScript
15.07.2026 18:21 · 👁 642
Виртуальные Scroll-контейнеры Йо, народ. Сегодня заценим инструмент ng-virtual-scroll-view. В прошлый раз я раскатывал про универсальные виртуализированные списки, которые внутри юзали одноосевой виртуальный scroll-контейнер. Решил из проекта ng-virtual-list выковать еще одну штуку — двухосевой виртуальный scroll-контейнер ng-virtual-scroll-view. Поддерживает Angular с 14 по 22 версии. API и примеры использования — в документации. Читай дальше 👉 Node.JS [ru]
Node.JS [ru] | Серверный JavaScript
15.07.2026 13:07 · 👁 555
⁣Неявный рассинхрон состояния при AsyncLocalSnapshot, EventEmitter и Symbol.asyncDispose Работаете с распределёнными очередями задач? Тогда наверняка сталкивались с AsyncLocalStorage для проброса контекста. Но связка AsyncLocalSnapshot с EventEmitter и забытый Symbol.asyncDispose приводят к багу, который воспроизводится раз на 50 запусков — контекст устаревает, состояние утекает. Почему контекст утекает AsyncLocalSnapshot замораживает контекст при создании, но колбэк от EventEmitter может жить дольше задачи. Если слушатель не удалён, он выполняется с устаревшим состоянием. В production это даёт stale data — задача обрабатывается с контекстом предыдущей или undefined. Production-пример ошибки Типичный сценарий: воркер запускает задачу, подписывается на события прогресса через emitter.on, но не чистит слушатель. В итоге в следующей задаче AsyncLocalSnapshot возвращает старый контекст. Код: const snapshot = new AsyncLocalSnapshot(als); emitter.on('event', snapshot.run(data => { console.log(als.getStore()); // устаревший контекст })); // Слушатель не удалён — баг Типичная ошибка Забывают реализовать Symbol.asyncDispose для временных слушателей. Или создают снапшот вне обработчика, вместо того чтобы делать это внутри. Совет: всегда используйте try/finally для очистки подписок. Практический совет Для долгоживущих слушателей не используйте AsyncLocalSnapshot — сохраняйте контекст в замыкании. Если нужно, чистите через finally или Symbol.asyncDispose: class Worker { async [Symbol.asyncDispose]() { emitter.removeAllListeners('progress'); } } Вывод: Управляйте временем жизни подписок явно — AsyncLocalSnapshot это моментальный снимок, а не долгоживущий контекст.
Чат поддержки
Ответим здесь же, обычно быстро
Здравствуйте! Напишите ваш вопрос — оператор ответит в этом чате.