- Replace fn()=> with traditional function() syntax in php_medium and php_large - 8 arrow function occurrences fixed across processWords/statsArr/caesar/lookupOps/nested array_map - Added diag_bugs.sh: diagnostic script for PHP pool exhaustion + ruby/medium cold anomaly - bench_full.sh RUNID=9250986: PASS=20 FAIL=0 (was PASS=18 FAIL=2) - ruby/medium cold=81549ms anomaly confirmed reproducible (3rd time), not a FAIL - Added doc/report-2026-05-20-bench-php-analysis.md
9.4 KiB
Анализ бенчмарка bench_full.sh — 2026-05-20
Контекст
Запущен полный бенчмарк bench-func/bench_full.sh (RUNID=9248232).
Namespace: fission-08f114ea3595cccf (sub: bench@bench.local).
4 языка × 4 размера (tiny/small/medium/large) + 4 архивных теста = 20 итого.
Результаты bench_full.sh
| LANG | SIZE | UPLOAD(ms) | COLD(ms) | HOT_AVG(ms) | STATUS |
|---|---|---|---|---|---|
| python | tiny | 2529 | 3317 | 1198 | OK |
| python | small | 2764 | 1387 | 1182 | OK |
| python | medium | 2762 | 1374 | 1185 | OK |
| python | large | 2769 | 1366 | 1653 | OK |
| nodejs | tiny | 3158 | 9410 | 1172 | OK (аномалия*) |
| nodejs | small | 2751 | 1559 | 1193 | OK |
| nodejs | medium | 2754 | 2471 | 1158 | OK |
| nodejs | large | 2745 | 1583 | 1190 | OK |
| ruby | tiny | 3142 | 3255 | 1162 | OK |
| ruby | small | 2737 | 1402 | 1181 | OK |
| ruby | medium | 3151 | 80451 | 115 | OK (аномалия!) |
| ruby | large | 1116 | 2448 | 104 | OK |
| php | tiny | 1137 | 2528 | 1200 | OK |
| php | small | 2747 | 1469 | 1158 | OK |
| php | medium | 2749 | — | — | COLD-TIMEOUT |
| php | large | 2725 | — | — | COLD-TIMEOUT |
| python | archive | 2749 | 1403 | 1176 | OK |
| nodejs | archive | 2777 | 1539 | 535 | OK |
| ruby | archive | 1367 | 821 | 787 | OK |
| php | archive | 2744 | 1575 | 1189 | OK |
ИТОГ: PASS=18, FAIL=2
*nodejs/tiny cold=9410ms — одиночный выброс, не воспроизводился.
Аномалия: ruby/medium cold=80451ms
Анализ
Проведено ×6 независимых прогонов (diag_bugs.sh, два запуска):
- 3780 / 1402 / 1384 / 3225 / 1435 / 1773 ms
Вывод: не воспроизводится. Разовый выброс (вероятно node pressure или transient network).
Статус: ЗАКРЫТ. Не баг.
Баг: PHP medium + large COLD-TIMEOUT
Первичная гипотеза (верна)
bench_full.sh генерирует PHP код для medium/large с arrow functions (PHP 7.4+):
// medium
array_map(fn($s) => strrev(strtoupper($s)), $words)
array_map(fn($x) => ($x - $m) ** 2, $data)
// large
array_map(fn($i) => array_map(fn($j) => ..., ...), ...)
PHP env на кластере — версия < 7.4. Arrow syntax → Parse error → pod возвращает 500.
PHP tiny/small и PHP archive — используют традиционный синтаксис без fn()=> → OK.
Механизм pool exhaustion (важно!)
При invoke сломанной функции:
- Executor берёт pool pod → специализирует под функцию
- PHP парсер: Parse error → возвращает 500
- Executor считает это ошибкой вызова → ретраит следующий pod
- 20 ретраев × 5s = 100s → COLD TIMEOUT
- За это время пул (
console-php-env) в namespace исчерпан
Следствие: php/large идёт ПОСЛЕ php/medium. К моменту его запуска пул уже разрушен → php/large тоже COLD TIMEOUT даже если бы его код был правильным.
Диагностика diag_bugs.sh — что мы делали
Создан скрипт bench-func/diag_bugs.sh с 6 тестами:
php-arrow-min— минимальный PHP сfn($x)=>$x*2php-version— толькоreturn PHP_VERSION(стандартный PHP)php-med-noarr— medium логика через foreach вместо arrowruby-med-1/2/3— ruby/medium ×3 независимых функции
Ошибки в процессе диагностики
Ошибка 1: SIGPIPE при | tee
Первый прогон завершился досрочно — скрипт через SSH pipe убивался SIGPIPE при прокрутке/чтении терминала. Исправлено: nohup + прямая запись в файл.
Ошибка 2: 5 параллельных прогонов diag_bugs.sh
В процессе диагностики случайно накопилось 5+ одновременных процессов diag_bugs.sh на VM (PIDs: 2476997, 2478955, 2480445, 2482045, 2482452). Все конкурировали за PHP pool → дополнительный pool exhaustion.
Следствие: тесты php-version и php-med-noarr тоже дали COLD TIMEOUT — не из-за собственного бага, а из-за занятого пула.
Что реально подтверждено vs что предполагается
| Факт | Статус |
|---|---|
fn()=> вызывает COLD TIMEOUT |
ПОДТВЕРЖДЕНО (×2 прогона) |
| PHP env версия < 7.4 | ПРЕДПОЛОЖЕНИЕ (php-version не дал ответа из-за pool exhaustion) |
| php-version FAIL = самостоятельный баг | ОПРОВЕРГНУТО — следствие pool exhaustion |
| php-med-noarr FAIL = PHP env broken | НЕ ПОДТВЕРЖДЕНО — тест не прошёл чисто |
Что НЕ удалось выяснить
- Точная версия PHP в env образе
- Работает ли
php-med-noarr(medium без arrow) в изолированном тесте
Механизм pool exhaustion — общая проблема
Одна функция с синтаксической ошибкой может "заморозить" весь PHP пул namespace:
- Сломанная функция → 20 ретраев × пул pod
- Пул исчерпан → все остальные PHP функции того же пользователя получают COLD TIMEOUT
- Пользователь видит что "рабочая" функция сломалась — не понимает почему
В реальном проде это критично: один неосторожный деплой = все PHP функции пользователя не отвечают.
Почему pod "держится"
Pool pod ≠ выполнение кода. Pod — контейнер-заготовка. При invoke:
- Executor специализирует pod (загружает код через /specialize)
- PHP парсер падает → 500 → executor ретраит СЛЕДУЮЩИЙ pod
- Каждый ретрай = новый pod из пула
Pod не "держится" в одном — executor расходует пул по одному pod'у за ретрай.
Системные решения (не реализованы)
- Circuit breaker в executor — после N провалов подряд для одной функции → вернуть ошибку, не трогать пул
- Синтаксическая валидация при upload —
php -l,python3 -m py_compile,ruby -c,node --check— сломанный код не попадает в систему - Pool size limit per namespace — ограничить max pods на env × namespace
Вариант 2 (валидация при upload) — реализуем в нашем коде (fission-console), остальные — в fission-bundle.
Предложения — что делать
Приоритет 1 (быстро): исправить bench_full.sh
Заменить arrow functions в PHP medium/large на традиционный синтаксис.
fn($s) => strrev(strtoupper($s))→function($s){ return strrev(strtoupper($s)); }fn($x) => ($x - $m) ** 2→ foreach цикл- Аналогично для large (вложенные array_map)
После фикса запустить bench_full.sh заново — должно быть PASS=20.
Приоритет 2 (чистая диагностика): проверить php-med-noarr
Убить фоновые процессы на VM, запустить одиночный тест php-version/php-med-noarr в изоляции — убедиться что PHP env работает для стандартного кода.
Приоритет 3 (системный): валидация кода при upload
Добавить в fission-console синтаксическую проверку кода перед созданием функции. Защита от pool exhaustion для всех пользователей.
Файлы
bench-func/bench_full.sh— основной бенчмарк (требует фикс PHP medium/large)bench-func/diag_bugs.sh— диагностический скрипт (создан в этой сессии)test-results/bench-func/— логи прогонов