Актуально для версии модуля Задачи <19.0.100 |
Именно в такой формулировке я получил инцидент, после последнего обновления. И да действительно при открытии профиля страница зависала и выпадала в ошибку 504 Gateway Timeout. Но было одно но, такое зависание происходило только при открытии профиля через глобальный поиск.
Причина
В отладчике Хрома был найден запрос на поиск задач, из-за выполнение которого всё и зависало. Одел HEV, взял монтировку и полез в модуль tasks.
Примечание. Очень был огорчён, что из настроек компонента search.title уже ничего не используется, другими словами на время решения проблемы отключить поиск по задачам можно было только закомментировав строки 951 и 952 в файле /bitrix/templates/bitrix24/components/bitrix/search.title/.default/script.js |
Итак в tasks косячил метод CTask::GetList();, причём вис он наглухо игнорируя лимит на выполнение скрипта php, поэтому собственно всё адекватно обрывал nginx по таймауту. А происходило так, потому что php ждал ответа от MySQL из-за очень плохо построенного запроса, вот он:
Поясню, нельзя помещать в IN подзапросы, только фиксированные значения, иначе, таким образом вы обречёте мускл выполнять этот подзапрос для каждой проверяемой строки таблицы. В моей таблице b_tasks 85384 строки не удивительно, что запрос вышел далеко за пределы таймаута nginx в 5 минут.
Решение
Аккуратно, не задевая лишних строк, монтировочкой выцарапываем костыль с надеждой на следующее обновление, а именно:
Файл: /bitrix/modules/tasks/classes/general/task.php
В строке 6596 объявляем глобальную переменную $DB:
global $DB; |
Строку 6605 (сверьтесь со скрином на всякий случай) заменяем на код, который произведёт запрос идентификаторов доступных для пользователя задач, и вставит их в оператор IN как фиксированные значения:
$dbTIDs = $DB->Query($accessSql); $arTIDs = []; while($arTID = $dbTIDs->Fetch()) $arTIDs[] = $arTID['TASK_ID']; $sql .= "T.ID IN (".implode(',', $arTIDs).")"; |
А ещё...
Кому интересно, данный запрос производит поиск по задачам, а эти вредные подзапросы в IN не что иное как проверка прав на задачи. Поэтому данная ошибка проявляется у разных пользователей по разному (у кого-то её вообще нет, а у кого-то от подвисаний до выпадания в 504), так сказать в меру прав доступа сотрудника к задачам, ну и конечно же играет роль общее количество задач.
Данная ошибка никогда не возникнет под учёткой администратора, так как ему в запрос не подставляется проверка прав, поэтому не торопитесь говорить пользователям: "Проблема на вашей стороне".