Files
fission-console/doc/report-2026-05-20-bench-php-analysis.md
T
“Naeel” a2e1723e33 bench: fix PHP arrow functions (fn()=> requires 7.4+), PASS=20/20 on PV
- 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
2026-05-20 08:27:32 +04:00

9.4 KiB
Raw Blame History

Анализ бенчмарка 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 сломанной функции:

  1. Executor берёт pool pod → специализирует под функцию
  2. PHP парсер: Parse error → возвращает 500
  3. Executor считает это ошибкой вызова → ретраит следующий pod
  4. 20 ретраев × 5s = 100s → COLD TIMEOUT
  5. За это время пул (console-php-env) в namespace исчерпан

Следствие: php/large идёт ПОСЛЕ php/medium. К моменту его запуска пул уже разрушен → php/large тоже COLD TIMEOUT даже если бы его код был правильным.

Диагностика diag_bugs.sh — что мы делали

Создан скрипт bench-func/diag_bugs.sh с 6 тестами:

  1. php-arrow-min — минимальный PHP с fn($x)=>$x*2
  2. php-version — только return PHP_VERSION (стандартный PHP)
  3. php-med-noarr — medium логика через foreach вместо arrow
  4. ruby-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:

  1. Сломанная функция → 20 ретраев × пул pod
  2. Пул исчерпан → все остальные PHP функции того же пользователя получают COLD TIMEOUT
  3. Пользователь видит что "рабочая" функция сломалась — не понимает почему

В реальном проде это критично: один неосторожный деплой = все PHP функции пользователя не отвечают.

Почему pod "держится"

Pool pod ≠ выполнение кода. Pod — контейнер-заготовка. При invoke:

  • Executor специализирует pod (загружает код через /specialize)
  • PHP парсер падает → 500 → executor ретраит СЛЕДУЮЩИЙ pod
  • Каждый ретрай = новый pod из пула

Pod не "держится" в одном — executor расходует пул по одному pod'у за ретрай.

Системные решения (не реализованы)

  1. Circuit breaker в executor — после N провалов подряд для одной функции → вернуть ошибку, не трогать пул
  2. Синтаксическая валидация при uploadphp -l, python3 -m py_compile, ruby -c, node --check — сломанный код не попадает в систему
  3. 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/ — логи прогонов