Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Какой же опыт мы получили? Во-первых, мы должны полностью понимать, как устроены зависимости в нашем коде, прежде чем использовать его в production.
Изначально мы предположили, что это могут быть утечки памяти в наших собственных обработчиках запросов, которые, в свою очередь, вызывали задержки. Мы проверили это предположение, с помощью нагрузочного тестирования изолированного приложения
{
"Start": "/start"
}
routes['Start'] = function()
{
}
что мешает иметь хеш таблицу вида routes['/users/:id'] = [callback1, callback2,..]. И просто в цикле искать соответствие текущему роуту?То, что если искать соответствие в цикле, то какой прок от хеш таблицы? Только вред — раньше структура была упорядочена, теперь непредсказуема. Если хотите список обработчиков для каждого патерна, достаточно сделать список обработчиков для каждого патерна.
[a, b, c, c, c, c, d, e, f, g, h]
То, что если искать соответствие в цикле, то какой прок от хеш таблицы?
Таким образом, при условии что на один и того же роут может быть повешено несколько обработчиков, приходится всегда перебирать весь массив.Дак что вам мешает сделать просто список обработчиков. Без хеша. Просто список.
routes[0] = {pattern: '/users/:id', callbacks: [callback1, callback2,..]};router.exist = function(route) {
return route in this.routes;
};
router.remove = function(route) {
if (this.exist(route))
delete this.routes[route];
};
router.add = function(route, callback) {
if ( ! this.exist(route))
this.routes[route] = callback;
};
Ничего не мешает, но похоже в Express (раз уж мы его обсуждаем), так не сделали и из-за этого у автора были проблемы.О, да? Спасибо, кэп. Тоже буду кепом — и вот вы предлагаете какой-то способ решения, а его минусуют. Вы спрашиваете почему минусуют, и я вам объясняю, почему ваш способ решения не очень хороший.
Вариант с просто списком по сравнению с хеш-таблицей ничем не лучшеНо ведь я уже написал, чем хэш хуже. Смотрите: «раньше структура была упорядочена, теперь непредсказуема». Хэш — неупорядоченная структура. Если вы будете «просто в цикле искать соответствие текущему роуту», вы будете искать их в случайном порядке.
куча кейсов, связанных с администрированием роутингаВот именно, администрированием, а не обработкой запросов. И это все равно будет не хуже текущей реализации.
О, да? Спасибо, кэп. Тоже буду кепом — и вот вы предлагаете какой-то способ решения, а его минусуют. Вы спрашиваете почему минусуют, и я вам объясняю, почему ваш способ решения не очень хороший.
Но ведь я уже написал, чем хэш хуже. Смотрите: «раньше структура была упорядочена, теперь непредсказуема». Хэш — неупорядоченная структура. Если вы будете «просто в цикле искать соответствие текущему роуту», вы будете искать их в случайном порядке.
даже при самом плохом варианте развития событий мы просто обойдем ее полностьюДело не в этом. Дело в том, что один урл может подходить сразу под несколько патернов. И фреймфорк должен в этом случае гарантировать, что выполнится первый (или последний) добавленный, а не случайный.
В случае со спискомВ каком именно случае со списком, который есть или как я предлагаю? Давайте еще раз попробую.
routes = [
['patern1', 'callback1'],
['patern1', 'callback2'],
['patern2', 'callback3']
];
routes = {
'patern1': ['callback1', 'callback2'],
'patern2': ['callback3'],
};
routes = [
['patern1', ['callback1', 'callback2']],
['patern2', ['callback3']]
];
routes['/users/:id']
router.add('/users/:id', function(id) {});
Оказалось, это было вызвано периодическим (10 раз в час) обновлением обработчиков в нашем коде из внешнего источника. Мы реализовали это удалением старых обработчиков и добавлением новых к массиву.
А если хранить его как строку, то сравнивать придется также все ключи из хэш-таблицы
module.exports = function(client, callback) {
client.cache(30000); // закешировать и исполнять не чаще 30 сек
dbImpress.users.find({ group: client.fields.group }).toArray(function(err, nodes) {
callback(nodes); // т.к. у каталога расширение .json то ответ упакуется в JSON и добавятся HTTP заголовки
});
}
Это вернет: [
{ "login": "Vasia Pupkin", "password": "whoami", "group": "users" },
{ "login": "Marcus Aurelius", "password": "tomyself", "group": "users" }
]
Ось X обозначает количество вызовов функции. На ней не показывается количество затраченного функцией времени, как на большинстве графиков. Порядок расположения не имеет значения, блоки просто отсортированы в лексикографическом порядке.
The x-axis spans the sample population. It does not show the passing of time from left to right, as most graphs do. The left to right ordering has no meaning (it's sorted alphabetically).
Node.js в огне