×

Чи існує можливість розширювати Express.js на льоту?

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Розробники WordPress кажуть, що WordPress стала такою популярною через можливість добре розширюватись, зокрема через свої хуки.

Що таке хуки у WordPress з технічної точки зору? — Робочий потік обробки HTTP-запиту у WordPress розбитий на певні етапи, кожен із яких має свою назву. Якщо ми хочемо написати хук, який спрацьовує під час ініціалізації запиту, то створюємо новий файл у «wp-content/plugins» і пишемо приблизно так:

<?php

function callback_name()
{
  echo 'Це мій плагін';
}

// Реєстрація хука
add_action('init', 'callback_name');

А у ядрі WordPress є такий код:

<?php

function init()
{
    echo 'Тут WordPress виконує свою "by default"-функціональність, і запускає хуки (код цієї функції розробники плагінів не чіпають)';
    do_action('init');
}

Таким чином, із хуків формують плагіни WordPress, підключають їх з адмінки.

Просто й зрозуміло. Тобто, не переписуючи ядро WordPress, завдяки хукам цю CMS можна переписати під бажану функціональність.

В контексті традиційних Node.js-фреймворків, таких як Express.js, так само просто розширити функціональність «на льоту» не вдасться, бо у таких фреймворках статично прописані middleware.

Припустимо, ми теж спробуємо вклинити хук в робочий потік:

const express = require('express');
const app = express();
const runHook = require('hooks').runHook;

// Тут runHook - це колбек
app.get('/', runHook ,function (req, res)
{
  res.send('Hello World!');
});

app.listen(3000);

В Express ми не можемо додавати хуки без перезапуску процеса. В PHP така схема працює, бо «перезапуск процеса» відбувається при кожному запиту.

Ніхто не підкаже, існує все-таки можливість вклинювати хуки без перезапуску Node.js-процеса?

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

syskall.com/...lating-the-connect-stack
Виглядає подібним на те, шо тобі потрібно

Я створив цю тему щоб пересвідчитись, що дійсно немає легких способів зробити розширення традиційних Node.js-фреймворків, типу Express.js, на льоту.

Для себе я вирішую цю проблему за допомогою OOP й ієрархічного Dependency Injection (від Angular). Завдяки DI, можна запросто змінити, наприклад, об’єкт з чергою тих самих хуків...

Дуже зручно, й не потребує перезапуску процеса.

ну ось я за декілька хвилин в гуглі найшов легкий спосіб)

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

Навряд ли в Express, который выполняется в тех же условиях, как и любой самописный код, есть встроенная возможность это обойти.

Можно написать собственный миддлваре, который будет читать фалы определенной папки и вызывать eval().

Вот только чем вас перезапуск не устраивает? Какие предпосылки?

Вот только чем вас перезапуск не устраивает? Какие предпосылки?

На скільки я собі це уявляю, то перезапуск процеса у Node.js — це не те ж саме, що graceful reload config у nginx. Тобто деякі запити можуть завершитись на півдорозі. А якщо це так, то само-собою зрозуміло, що це погано. Плюс — краще щоб була можливість без прямого доступу до терміналу, просто з веб-адмінки зайти й підключити/відключити потрібний плагін.

На скільки я собі це уявляю, то перезапуск процеса у Node.js
ще шукаю, проте мені здається, що таки graceful. Навіть, якщо це Ctrl + C у консолі,

Control+C is used to kill a process with the signal SIGINT, and can be intercepted by a program so it can clean its self up before exiting, or not exit at all.
Тож як розробники NodeJS хоч трохи турбувалися про системи у проді, вони мают нормально працювати з такими сигналами — спочатку обробити усі встановленні підкючення.

[UPD] простіше за все написати скрипт, який(хоч би і sleep) буде дуже довго оброблятися. А потім подивитися, як презапуск себе буде поводити. Я ж правильно розумію, якщо там саме «graceful shutdown», то питання щодо хуків в Express буде не актуальним?

Навіть якщо це так, то з веб-адмінки не перезапустиш процес.

P.S. Це я набиваю ціну своєму дітищу, яке працює з використанням Dependency Injection, і яке вміє робити описані тут фінти =).

то з веб-адмінки не перезапустиш процес
а чи воно треба? хіба що плануєте з адмінки додавати кастомні мідлваре, просто завантажуючи файл через адмінку.

Там за посиланням дофіга досить відомих/випробуваних тулзів, що перезапускають сервер при змінах у файловій системі. Один раз запустив і забув.

[UPD] попередження: я ноду хіба що палкою штрикав здалеку. «Хлопці піднімали ноду та на мене надихали». Тож, можу просто щось не знати.

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

а чи воно треба?
Я не даром навів приклад WordPress і згадав, через що саме ця CMS така популярна...
Там за посиланням дофіга досить відомих/випробуваних тулзів, що перезапускають сервер при змінах у файловій системі. Один раз запустив і забув.

Так, я про них знаю. Я використовую pm2, ця тулза робить багато чого, в тому числі вміє перезапускати Node.js-процес, коли він падає, чи коли змінились source-файли.

Щойно проексперементував з одним з найпопулярніших процес-менеджерів для Node.js — pm2.

У нього є такі опції для перезапуску:
— pm2 start <file|json|stdin|app_name|pm_id...>
— pm2 restart <id|name|all|json|stdin...>
— pm2 reload <name|all>

Для емуляції клієнтських запитів, я запустив відому утиліту `ab` наступним чином (50k запитів з конкуренцією у 100 запитів за раз):

ab -n 50000 -c 100 localhost:8080/

І поки вона виконувала свої запити, я по черзі запускав pm2 start, pm2 restart, pm2 reload — усі вони валили процес і `ab` завершувалась так:

apr_socket_recv: Connection reset by peer (104)

Тобто схоже немає таки можливості перезапуску Node.js-процеса graceful.

Тобто схоже немає таки можливості перезапуску Node.js-процеса graceful.

ну значить тобі прийдеться писати свій процес-менеджер з такою можливістю. Або придумувати, як підключати до процеса кусок говнокода на ходу. Або написати апачеподібний http сервер на ноді, який буде для кожного реквеста створювати новий процес

(хвилинка важкої наркоманії на доу)

(хвилинка важкої наркоманії на доу)

Андрюха, вибачай, але ти очевидно берешся оцінювати те, в чому й сам не тямиш. Твоя іронія явно джуніорська, і ти не спромігся прочитати хоча б ці 12 коментарів, які є у цій темі на даний момент (якщо б прочитав, то побачив би що для мене такої проблеми не існує)...

так я і не заперечую, шо я абсолютно не тямлю в ноді)
просто мені здається, шо ти намагаєшся вирішити свої проблеми не тими інструментами (хоча хз, як там у вас, я ж в ноді не тямлю).
Ну і я не розумію, в чому проблема, є ж багато способів рішити твою задачу, тільки я не розумію, навіщо таке робити

Якщо ти не тямиш, то не використовуй, будь-ласка, порівняння з «важкою наркоманією» і не малюй великі очі в коментарях, залиш це людям, які можуть це оцінювати.

Ну і я не розумію, в чому проблема

Спеціально для тебе можу повторитись: дуже зручно, коли ти можеш зайти через веб-адмінку й завантажити вподобаний плагін, натиснути кнопку «Активувати» — і все працюватиме. Коли є необхідність заходити через термінал, рубати незавершені запити — це помітно гірше...

не використовуй, будь-ласка, порівняння з «важкою наркоманією»
з важкою наркоманією я порівнював тільки те, шо написав особисто я в своєму коментарі)

pm2.keymetrics.io/...r-mode/#graceful-shutdown

все там є ;)
писати самому не дуже зручно, проте автоматично не прийняти рішення, чи можна обірвати обробку чи як саме завершити роботу з БД.

просто з веб-адмінки зайти й підключити/відключити потрібний плагін.
о_о а в вордпресі код плагіна теж в адмінці пишеться?)

Можна підключити плагін, написаний кимось іншим. Ви заходите в адмінку, шукаєте плагін в інтернеті, натискаєте кнопку «Встановити» (він завантажується автоматично на бекенд), після чого активуєте його. Це все робиться саме з веб-адмінки.

Підписатись на коментарі