Roadmap Rozprawy Doktorskiej

Od publikacji 30-stron do dysertacji 100+ stron

Status bazowy (2026-05-29): 1 gotowa publikacja, 30 stron, Minor Revision / Accept
Cel: rozprawa doktorska ~120–140 stron + 2 dodatkowe publikacje
Oś narracyjna: Energetyczna efektywność środowisk uruchomieniowych JavaScript w obliczeniach bezserwerowych — od pomiaru do systemu


1. Teza główna rozprawy

Wybór środowiska uruchomieniowego JavaScript ma statystycznie istotny i praktycznie mierzalny wpływ na zużycie energii w obliczeniach bezserwerowych; wpływ ten jest systematycznie zależny od charakterystyki workloadu, architektury procesora oraz liczby wywołań funkcji — i może być eksploatowany przez autonomiczny system zarządzania energią na platformach FaaS.

Obecna Publikacja 1 dowodzi pierwszego członu tezy (pomiar, porównanie, TOPSIS).
Publikacja 2 rozszerza weryfikowalność (nowe runtimes, ARM, obciążenie współbieżne).
Publikacja 3 zamyka pętlę: buduje system, który tę wiedzę aktywnie wykorzystuje.


2. Struktura docelowa dysertacji (~130 stron)

RozdziałTreśćSzacowane strony
1. WstępMotywacja, teza, cel, wkłady, struktura15–20
2. Przegląd literaturyRozbudowany (3–4× obecny), nowe obszary: LLRT, carbon-aware, ML for energy30–40
3. MetodologiaObecna + nowe platformy, runtimes, narzędzia pomiarowe20–25
4. Wyniki Pub. 1Obecna praca (rozbudowana: +ARM, +LLRT, +workloady)25–30
5. Wyniki Pub. 2Workload characterization + ML-based selector20–25
6. Wyniki Pub. 3System ERS (Energy-Runtime Scheduler)15–20
7. Dyskusja i wnioskiSyntetyczna odpowiedź na tezę10–15
AppendicesDane surowe, kod, konfiguracje5–10
Łącznie~120–145 stron

3. Rozszerzenia Publikacji 1 (obecna praca → wersja dysertacyjna)

3.1 Dodatkowe runtimes (+8–12 stron)

LLRT (Low Latency Runtime) — Amazon, 2024

  • Oparty na QuickJS (brak JIT, AoT-like execution)
  • Specjalnie zaprojektowany dla cold-start serverless — deklaruje 11× szybszy cold start vs Node.js
  • Hipoteza H-LLRT: LLRT osiąga energię cold-start ~50% niższą niż Node.js, ale steady-state energy jest wyższe od wszystkich runtimeów JIT powyżej N≈30 wywołań, ze względu na brak optymalizacji hot-path
Eksperyment: #JE-EXP-7 — LLRT vs pozostałe runtimes
Workloady: CPU-bound, cold start (te same co EXP-1 dla porównywalności)
Pomiar: E_cold (spawn + 1 request), E_ss (plateau, N=200 requests)
Sprzęt: P1 (Skylake)
Hipoteza falsyfikowalna:
  H7a: E_cold(LLRT) < E_cold(Bun) < E_cold(Node.js)  [brak JIT overhead]
  H7b: E_ss(LLRT) > E_ss(Bun) i E_ss(LLRT) > E_ss(Node.js)  [brak JIT plateau]
  H7c: Break-even(LLRT vs Bun) w N ∈ [20, 60] wywołań

EdgeJS (następca WinterJS, SpiderMonkey-based)

  • WinterJS (Shopify) został porzucony — projekt nie jest utrzymywany od 2024, aktywność GitHub zamrożona
  • Następcą jest EdgeJS (https://edgejs.org/) — oparty na tym samym silniku SpiderMonkey, ale aktywnie rozwijany jako standardowy edge runtime
  • Nadal unikalny wkład badawczy: EdgeJS to pierwsze środowisko oparte na SpiderMonkey w benchmarku energetycznym, umożliwia porównanie 3 różnych JIT (V8, JavaScriptCore, SpiderMonkey) w tym samym protokole
  • ⚠️ Ryzyko: EdgeJS jest wczesnym projektem — zweryfikować stabilność HTTP API przed włączeniem do eksperymentów
  • Hipoteza: SpiderMonkey (EdgeJS) ma wolniejszy warm-up JIT niż V8 i JSC, ale wyższy steady-state throughput dla workloadów memory-bound (SpiderMonkey Warp JIT optymalizuje pod kątem memory locality)

3.2 Platforma ARM — walidacja architektury (+12–15 stron)

Eksperyment JE-EXP-8 — Ampere Altra (AArch64)

Platforma P3: Ampere Altra Q80-33 lub AWS Graviton3 (c7g instance)
Pomiar energii: Hardware PMU (perf-power), ODPM (On-Die Power Monitor) dla Altra
Sprzęt alternatywny (tańszy): Raspberry Pi 5 (ARM Cortex-A76, RAPL-equivalent via vcgencmd)

Hipotezy:
  H8a: Rankingi energetyczne (Bun < Deno < Node.js dla I/O-bound) są zachowane na ARM
  H8b: Bezwzględna przewaga Bun przy I/O-bound jest mniejsza na ARM (< 50% vs 74% x86-64),
       bo eliminacja libuv narzutu jest mniej istotna na architekturze z wydajniejszymi
       wywołaniami systemowymi
  H8c: JavaScriptCore ma relatywnie wyższą efektywność na ARM (Apple origin — JSC
       zoptymalizowane pod AArch64 przez lata na iOS)

Dlaczego to ważne dla dysertacji: pełna trójkąt walidacji (Skylake, Coffee Lake, ARM) — generalizowalność na wszystkie klasy serwerów FaaS.

3.3 Kompatybilność API jako wymiar energetyczny (+8–12 stron, potencjalny RQ-EXT)

To niedoceniany wymiar w literaturze: migracja z Node.js na Bun/Deno/EdgeJS nie jest darmowa — wymaga weryfikacji kompatybilności API. Co ważniejsze, polyfilling niezgodnych API zmienia profil energetyczny.

Kontekst standardyzacji

WinterTC (Web-interoperable Runtimes Community Group, https://wintertc.org/) definiuje “Minimum Common Web Platform API” — zbiór API, które wszystkie środowiska uruchomieniowe powinny implementować natywnie: fetch, crypto.subtle, TextEncoder/Decoder, URL, ReadableStream. Funkcje używające wyłącznie WinterTC API są przenośne między Node.js, Deno, Bun i EdgeJS.

Znane luki kompatybilności:

API / ModułNode.jsBunDenoEdgeJS
node:vm (eval sandbox)❌ (partial)
node:child_process exec✅ (partial)✅ (—allow-run)
Native addons (node-gyp)⚠️ limited
Worker threads✅ (API diff)✅ (Web Workers)
node:crypto legacy API✅ (node: compat)
npm packages (fs, path)✅ (via node:)⚠️

Pytanie badawcze (opcjonalny RQ-EXT)

RQ-COMPAT: Jak użycie API spoza WinterTC wpływa na zużycie energii — czy polyfillowanie brakujących API w Bun/Deno wprowadza mierzalny narzut energetyczny (> 5%) w stosunku do natywnej implementacji Node.js?

Hipoteza H-COMPAT-1: Funkcje używające wyłącznie WinterTC-kompatybilnych API wykazują identyczny ranking energetyczny niezależnie od runtimes. Narzut polyfilli (np. node:crypto emulowany przez WebCrypto) wynosi < 3% dla typowych operacji haszowania.

Hipoteza H-COMPAT-2: Ponad 60% funkcji z publicznych repozytoriów serverless (GitHub, OpenFaaS Hub) używa wyłącznie WinterTC API lub API wspieranych przez Bun — co oznacza, że energia oszczędna przez zmianę runtimeu jest dostępna dla > 60% realnych funkcji bez kodu zmian.

Podejście empiryczne

1. Audit 500 funkcji z GitHub (tag: aws-lambda, serverless-function)
   → klasyfikacja: WinterTC-only | Node-only | requires-polyfill

2. Dla każdej kategorii: zmierzyć E(Node.js) vs E(Bun) vs E(Deno)
   → sprawdzić czy H-COMPAT-1 zachodzi

3. Wersje "z polyfill" vs "bez polyfill" dla tej samej funkcji
   → delta energii per polyfill type

Ten wątek naturalnie łączy się z Pub. 2 (dataset funkcji) — te same 500 funkcji służą zarówno do klasyfikacji AST, jak i do audytu kompatybilności.

3.4 Nowe kategorie workloadów (+5–8 stron)

WorkloadUzasadnienieHipoteza
SQLite embeddedORM queries są dominującym workloadem w lambdach bazodanowychBun (wbudowany SQLite) vs Node.js (better-sqlite3) — przewaga Bun przez brak FFI
Streaming HTTP (SSE/chunked)Realtime dashboards, AI token streamingDeno (Streams API natywna) vs Node.js (legacy stream)
Crypto/hashing (bcrypt, SHA-256)Auth middleware, token validationNode.js (natywny crypto moduł OpenSSL) może wygrywać energetycznie
ML inference (ONNX.js)Serverless AI — szybko rosnący use caseCzy Bun/Node.js/Deno różnią się przy workloadach GPU-offloaded?

4. Publikacja 2 — Charakteryzacja workloadów i predykcja optymalnego runtime

Tytuł roboczy

“Workload-Aware Energy Prediction for JavaScript Serverless Functions: A Static Analysis Approach”

Motywacja

Publikacja 1 odpowiada na pytanie “który runtime jest energooszczędniejszy dla danej kategorii”. Problem praktyczny: operator platformy FaaS nie wie z góry, do której kategorii należy nowa funkcja. Czy da się przewidzieć optymalny runtime na podstawie kodu źródłowego?

Pytania badawcze

  • RQ-P2-1: Jakie statyczne cechy kodu źródłowego funkcji JS korelują z kategorią workloadu i energią per runtime?
  • RQ-P2-2: Czy prosty klasyfikator ML (decision tree, RF) na cechach AST jest w stanie przewidzieć energooszczędny runtime z dokładnością > 80%?
  • RQ-P2-3: Jak zachowuje się predykcja dla funkcji “mieszanych” (niespadających jednoznacznie w jedną kategorię)?
  • RQ-P2-4: Jak daleko jest od statycznej predykcji do predykcji online (na podstawie pierwszych N=10 wywołań)?

Podejście techniczne — Babel AST jako fundament

Co to jest AST i dlaczego Babel

AST (Abstract Syntax Tree) to drzewiasta reprezentacja struktury kodu — parser czyta tekst .js/.ts i zamiast traktować go jako ciąg znaków, buduje hierarchię węzłów: “tu jest deklaracja funkcji”, “tu jest wywołanie fetch”, “tu jest pętla for”.

@babel/parser to de facto standardowy parser JS/TS w ekosystemie — używają go ESLint, Prettier, Next.js, Vite. Produkuje AST zgodny ze standardem ESTree, rozszerzony o TypeScript, JSX i dekoratory. Kluczowe: parsuje kod bez jego uruchamiania, w < 50 ms nawet dla dużych plików.

Dlaczego statyczna analiza AST zamiast uruchomienia funkcji?
Operator platformy FaaS widzi tylko kod źródłowy przy deployu — nie może 500 razy uruchomić funkcji żeby zmierzyć energię. AST daje klasyfikację w czasie deploy, bez żadnego execution overhead. To jest przewaga praktyczna nad profilowaniem dynamicznym.

Ograniczenie, które należy opisać w dysertacji: AST jest statyczny — nie widzi wzorców zależnych od środowiska wykonania: require(dynamicString), warunkowych importów (if (env === 'prod') import(...)), ani pośrednich wywołań przez callback. Stąd cel H-P2-2 to 75%, nie 100%, i stąd Pub. 2 proponuje online profiling jako uzupełnienie dla niejasnych przypadków.

Jak działa ekstrakcja cech

Przykład — ta funkcja:

export async function handler(req) {
  const resp = await fetch("https://api.example.com/data");
  const json = await resp.json();
  return json.items.map(x => x.name.toUpperCase()).join(", ");
}

Po sparsowaniu przez Babel i przejściu drzewa (@babel/traverse) ekstraktor zlicza:

ioCallDensity    = 1 fetch call / 5 LOC = 0.20   → sygnał I/O-bound
asyncDepth       = 2 (dwa zagnieżdżone await)
cpuLoopDensity   = 0 (map() jest functional, brak for-loop)
stringOps        = 2 (.toUpperCase(), .join())    → mały sygnał SSR
nativeModules    = 0 (samo fetch, brak fs/crypto)

Feature vector: [0.20, 2, 0, 0.4, 0] → klasyfikator przewiduje: I/O-bound → Bun

Inny przykład — funkcja CPU-bound:

export function handler(req) {
  let result = 0;
  for (let i = 0; i < 1_000_000; i++) {   // ← cpuLoopDensity++
    result += Math.sqrt(i) * Math.sin(i);   // ← mathOpDensity++
  }
  return { result };
}
ioCallDensity    = 0
asyncDepth       = 0
cpuLoopDensity   = 1 for-loop / 4 LOC = 0.25
mathOpDensity    = 2 (sqrt, sin)
nativeModules    = 0

Feature vector: [0, 0, 0.25, 2, 0] → klasyfikator przewiduje: CPU-bound → Bun

Implementacja ekstraktorów (pseudokod TypeScript)

import { parse } from "@babel/parser";
import traverse from "@babel/traverse";
 
const IO_CALLS = new Set(["fetch","readFile","writeFile","query","get","post","put","delete"]);
const MATH_FNS = new Set(["sqrt","sin","cos","pow","abs","floor","ceil","random"]);
 
export function extractFeatures(source: string): FeatureVector {
  const ast = parse(source, { sourceType: "module", plugins: ["typescript"] });
 
  let ioCalls = 0, asyncDepth = 0, cpuLoops = 0, mathOps = 0;
  let stringTemplates = 0, totalNodes = 0;
 
  traverse(ast, {
    CallExpression({ node }) {
      totalNodes++;
      const name = node.callee.type === "Identifier" ? node.callee.name
                 : node.callee.type === "MemberExpression" ? node.callee.property.name
                 : "";
      if (IO_CALLS.has(name))   ioCalls++;
      if (MATH_FNS.has(name))   mathOps++;
    },
    ForStatement()      { cpuLoops++; },
    WhileStatement()    { cpuLoops++; },
    AwaitExpression(path) {
      const depth = path.getAncestry().filter(p => p.isAwaitExpression()).length + 1;
      asyncDepth = Math.max(asyncDepth, depth);
    },
    TemplateLiteral()   { stringTemplates++; },
  });
 
  const loc = source.split("\n").length;
  return {
    ioCallDensity:       ioCalls / loc,
    asyncDepth,
    cpuLoopDensity:      cpuLoops / loc,
    mathOpDensity:       mathOps / loc,
    stringTemplateDensity: stringTemplates / loc,
  };
}

Uwaga implementacyjna: @babel/traverse jest heavy dependency (~2 MB). Dla CLI tool można użyć lżejszego acorn + estree-walker (~80 KB) dającego ten sam wynik dla czystego JS (bez TS/JSX). Dla pełnego wsparcia TypeScript Babel pozostaje najlepszym wyborem.

Pełny pipeline

[Kod źródłowy .js/.ts]
      ↓
[@babel/parser → AST]        ~10–50 ms, bez uruchamiania kodu
      ↓
[traverse → FeatureVector]   5 wymiarów liczbowych
      ↓
[Random Forest Classifier]   wytrenowany na 400 zlabelowanych funkcjach
      ↓
[Predykcja + confidence]     {Bun | Deno | Node.js}, confidence 0–1
      ↓ (jeśli confidence < 0.70)
[Online Profiling fallback]  pierwsze 10 wywołań + pomiar per-request energy
      ↓
[Finalna rekomendacja]

Dataset treningowy

  • Zbieramy 200–500 funkcji serverless z FunctionBench, GitHub (tagi: serverless-function, aws-lambda, faas), Serverless Framework examples — ⚠️ OpenFaaS Hub jest nieaktywny od 2023, nie używać jako główne źródło
  • Labelujemy każdą funkcję przez uruchomienie w protokole Pub. 1 i pomiar energii
  • Split: 70/15/15 train/val/test

Hipotezy

H-P2-1: Cechy AST (I/O call density, async depth) są wystarczające do predykcji kategorii
         workloadu z F1 > 0,80 (w 5 kategoriach)

H-P2-2: Klasyfikator statyczny (bez uruchomienia) osiąga dokładność predykcji optymalnego
         runtime na poziomie > 75% (baseline: random = 33%)

H-P2-3: Online profiling (pierwsze 10 wywołań + pomiar energii per-request) poprawia
         dokładność do > 95% (dynamiczna korekta)

H-P2-4: Wrażliwość na wersje runtime jest < 5% — klasyfikator wytrenowany na v1 działa
         na v2 bez re-trenowania

Co zakodować

Narzędzie: js-energy-profiler — CLI tool:

npm install -g js-energy-profiler
js-energy-profiler analyze ./my-function.js
# Output: "Predicted workload: I/O-bound (confidence: 0.87)"
#         "Recommended runtime: Bun (estimated -71% energy vs Node.js)"
#         "Confidence: high (AST features: 12 fetch calls, 2 fs calls, 0 CPU loops)"

Komponenty do implementacji:

  1. packages/ast-analyzer/ — parser cech statycznych (Babel AST → feature vector)
  2. packages/runtime-classifier/ — serializowalny model RF (onnx lub json-serialized)
  3. packages/energy-profiler-cli/ — CLI wrapper
  4. Testowany na zbiorze 500+ funkcji z Pub. 2

Venue: ICSE’27/28 (sekcja empiryczna), FSE’27 (tool track), MSR’27


5. Publikacja 3 — System energetyczno-świadomy: ERS (Energy-Runtime Scheduler)

Tytuł roboczy

“ERS: An Energy-Aware Runtime Scheduler for Multi-Tenant JavaScript Serverless Platforms”

Motywacja i gap

Skąd pomysł

Pub. 1 i Pub. 2 razem dają operatorowi platformy FaaS dwie rzeczy: tabelę “który runtime jest optymalny dla której kategorii workloadu” oraz narzędzie do automatycznej klasyfikacji nowych funkcji. Naturalne pytanie, które pojawi się przy każdej prezentacji tych wyników: “OK, ale czy to działa na żywej platformie? I o ile procent oszczędza?”

Bez Pub. 3 rozprawa kończy się na poziomie rekomendacji (“powinieneś używać Bun dla I/O-bound”). Z Pub. 3 kończy się na poziomie systemu (“zbudowaliśmy scheduler, który robi to automatycznie i zmierzaliśmy -22% energii w 7-dniowym teście”). To fundamentalna różnica dla recenzenta.

Luka w literaturze

Istniejące systemy carbon-aware FaaS (LACE-RL Sun et al. 2026, GreenCourier Chadha et al. 2023) operują na jednym wymiarze decyzyjnym: kiedy uruchomić funkcję (temporal shifting). Żaden z nich nie zadaje pytania na czym ją uruchomić. ERS łączy oba wymiary:

Literatura dotychczas:          ERS (nasza propozycja):
  KIEDY uruchomić?         →      KIEDY uruchomić?
  (carbon intensity signal)       (carbon intensity signal)
                           +      NA CZYM uruchomić?
                                  (runtime selection per workload)
                           +      JAK DŁUGO TRZYMAĆ CIEPŁĄ INSTANCJĘ?
                                  (LACE-RL λ_idle z Pub.1)

To trójwymiarowa przestrzeń decyzyjna, której nikt nie zbadał empirycznie na rzeczywistym sprzęcie.

Dlaczego “system paper”, nie kolejny benchmark

Samo napisanie “powinno działać” nie wystarczy — potrzebny jest zamknięty eksperyment: platforma przyjmuje ruch, scheduler podejmuje decyzje, RAPL mierzy rzeczywisty pobór mocy, porównujemy z baselinami. Taki eksperyment ma dwie wartości jednocześnie: (a) weryfikuje hipotezy Pub. 1 i Pub. 2 w warunkach produkcyjnych, (b) dostarcza open-source artefakt, który inni mogą uruchomić i rozszerzyć.

Analogia z literatury systemowej: nie wystarczy udowodnić, że kompresja danych oszczędza miejsce — trzeba zbudować system plików i zmierzyć przepustowość.

Co ERS wnosi ponad TOPSIS z Pub. 1

Model TOPSIS z Pub. 1 to decyzja statyczna przy deployu — wybieramy runtime raz, na podstawie deklarowanej kategorii funkcji. ERS dodaje trzy dynamiczne komponenty, których TOPSIS nie ma:

  1. Automatyczna klasyfikacja (Pub. 2 AST Analyzer) — operator nie musi ręcznie deklarować kategorii
  2. Online feedback — jeśli zmierzona energia odbiega od profilu (np. funkcja “I/O-bound” zaczęła robić ciężkie obliczenia po aktualizacji kodu), scheduler koryguje przypisanie runtimeu
  3. Carbon-aware temporal shifting — ten sam workload może być przekierowany na inny runtime w godzinach wysokiej emisji sieci (np. nocą, gdy energia jest “brudniejsza”, preferujemy runtime z niższym bezwzględnym poborem mocy)

Architektura ERS

┌─────────────────────────────────────────────────────────────┐
│                    ERS — Control Plane                       │
│                                                              │
│  ┌──────────────┐  ┌───────────────┐  ┌──────────────────┐ │
│  │ Workload     │  │ Carbon-Aware  │  │  Keep-Alive      │ │
│  │ Classifier   │  │  Policy       │  │  Optimizer       │ │
│  │ (Pub.2 model)│  │ (grid carbon  │  │  (LACE-RL        │ │
│  │              │  │  intensity)   │  │   λ_idle=0.20)   │ │
│  └──────┬───────┘  └──────┬────────┘  └──────┬───────────┘ │
│         └─────────────────┴───────────────────┘             │
│                           │                                  │
│                    ┌──────▼──────┐                          │
│                    │  Scheduler  │                           │
│                    │  Decision   │                           │
│                    └──────┬──────┘                          │
└───────────────────────────┼─────────────────────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        ▼                   ▼                   ▼
  [Node.js pool]      [Bun pool]         [Deno pool]
  (SSR functions)    (I/O functions)  (memory functions)
        │                   │                   │
        └───────────────────┴───────────────────┘
                            │
                     [RAPL Monitor]
                     (feedback loop)

Kluczowe komponenty:

  1. Workload Classifier (z Pub. 2) — na podstawie kodu funkcji przy deployu
  2. Keep-Alive Optimizer — LACE-RL z z Pub. 1, decyduje o TTL per-instance
  3. Carbon-Aware Policy — integracja z Electricity Maps API, przesuwa obciążenie do “zielonych” godzin gdy to możliwe
  4. Energy Monitor — zbiera RAPL real-time, zamkniętopętlowy feedback do schedulera

Hipotezy

H-P3-1: ERS redukuje całkowite zużycie energii platformy FaaS o > 20% vs baseline
         (wszystkie funkcje na Node.js) przy tym samym throughput i SLA

H-P3-2: ERS redukuje energię o > 30% w stosunku do naiwnego "zawsze Bun" — ze względu
         na SSR workloady, gdzie Node.js jest lepszy

H-P3-3: Komponent carbon-aware (przesunięcie wywołań na godziny niskiej emisji) redukuje
         emisję CO₂ o > 10% w 30-dniowym oknie, bez naruszenia deadline'ów funkcji

H-P3-4: Overhead schedulera ERS (latencja decyzji) jest < 2 ms na deployment event
         i < 0.1% na per-request overhead — pomijalny operacyjnie

Platforma testowa — wybór stacku

Kluczowa decyzja projektowa: Kubernetes-based FaaS (Knative, OpenFaaS) vs bare-metal dispatcher.
Rekomendacja: minimalny własny dispatcher — bo Kubernetes control plane zużywa 5–15 W samodzielnie, co zanieczyszcza pomiary RAPL i wymaga osobnego baseline’u energetycznego.

Opcja A (rekomendowana): Własny Minimal Process Pool Manager (~350 LOC Go)

// Architektura: prosty HTTP reverse proxy + pool procesów runtimeów
//
//   [HTTP Request]
//        ↓
//   [ERS Router] → workload classifier → wybór runtimeu
//        ↓
//   [Process Pool]
//     Node.js pool (pre-warmed, SSR functions)
//     Bun pool     (pre-warmed, I/O functions)
//     Deno pool    (pre-warmed, memory functions)
//        ↓
//   [RAPL Monitor] → feedback do schedulera

Zalety:

  • Zero overhead konteneryzacji w pomiarach RAPL (bezpośredni fork())
  • Pełna kontrola nad warm-up, keep-alive TTL, process recycling
  • ~350 LOC w Go = wiarygodny, peer-reviewowalny artefakt badawczy
  • Żaden reviewer nie powie “wyniki zafałszowane przez Kubernetes overhead”

Wady:

  • Brak izolacji procesów między tenant-ami (akceptowalne dla single-node research)

Opcja B: Nuclio (https://nuclio.io/)

Jeśli potrzebne środowisko zbliżone do produkcji z izolacją:

  • Nuclio działa w trybie standalone (bez Kubernetes: nuclio-standalone binary)
  • Napisany w Go, minimalny overhead (~50 MB RAM dla controllera)
  • Ma natywne wsparcie dla Node.js i custom runtimes przez “function processor” plugin
  • REST API do zarządzania funkcjami → ERS może być zewnętrznym schedulem przez HTTP
  • Dobre wsparcie dla RAPL-based energy monitoring (brak własnej metryki, ale łatwa integracja)
# Uruchomienie Nuclio standalone (bez Kubernetes):
docker run -p 8070:8070 -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  nuclio/dashboard:latest
# ERS = zewnętrzny serwis wywołujący nuclio REST API do routingu

Dlaczego Nuclio zamiast OpenFaaS:

  • OpenFaaS wymaga Kubernetes lub faasd (jego bare-metal wariant) + dodatkowy operator
  • OpenFaaS nie ma wbudowanego custom runtime API (tylko Docker containers)
  • Nuclio ma “custom processor” — można podpiąć natywny proces Bun/Node/Deno bez kontenerów
  • OpenFaaS community coraz bardziej komercjalizuje projekt (Enterprise focus)

Opcja C: faasd (OpenFaaS bez Kubernetes)

Jeśli jednak OpenFaaS ze względu na znajomość ekosystemu:

  • faasd (https://github.com/openfaas/faasd) = OpenFaaS na containerd bez Kubernetes
  • Single binary, ~30 MB RAM overhead, działa na bare-metal
  • Ale: każda funkcja to osobny kontener → cold-start energy overhead od containerd start
  • Mniej czyste pomiary niż Opcja A

Wybrana konfiguracja

Hardware: P1 (Skylake, 16 GB RAM) jako single-node serverless platform
Stack: Opcja A (własny dispatcher) lub Nuclio standalone
RAPL: pomiar bezpośredni przez /sys/class/powercap/intel-rapl/
Prometheus + custom RAPL exporter (Grafana dashboard)
Electricity Maps API (carbon intensity, free tier dla PL/DE)

Funkcje testowe:
  - 20 funkcji z GitHub (klasyfikowane przez AST Analyzer z Pub. 2)
  - 5 funkcji bazowych z Pub. 1 (znane profile energetyczne jako sanity check)
  - Synthetic traffic: Poisson process λ ~ ServerlessReport 2024 real traces

Porównanie z baseline

BaselineOpis
B1: Static Node.jsWszystkie funkcje na Node.js, brak keep-alive optimizer
B2: Static BunWszystkie funkcje na Bun
B3: TOPSIS-staticRuntime wybierany raz przy deploy (nasze Pub. 1 wyniki)
ERSDynamic: runtime + keep-alive + carbon-aware

Venue: EuroSys’27, SoCC’27 (ACM Symposium on Cloud Computing), ATC’27


6. Co zakodować — priorytety implementacyjne

6.1 Priorytet 1: Benchmark Suite (dla Pub. 1, już jest szkielet)

code/
├── workloads/
│   ├── cpu-fib.js          # Fibonacci (CPU-bound)
│   ├── io-fetch.js          # HTTP fetch chain (I/O-bound)
│   ├── mem-matrix.js        # Large matrix operations (memory-bound)
│   ├── ssr-template.js      # String templating (SSR-bound)
│   ├── sqlite-queries.js    # NEW: SQLite embedded (Pub.1 extension)
│   └── crypto-hash.js       # NEW: bcrypt/SHA-256 (Pub.1 extension)
├── harness/
│   ├── rapl_monitor.py      # RAPL sysfs reader
│   ├── run_experiment.sh    # Orchestrator (warmup → measure → export)
│   └── stats.py             # Mann-Whitney U, Cohen's d, Bonferroni
└── analysis/
    ├── topsis.py            # TOPSIS model z Pub. 1
    └── plot_results.py      # Matplotlib boxplots + barplots

Koszt: 2–3 tygodnie, standalone wartość jako open-source (npm package + bash scripts)

6.2 Priorytet 2: AST Analyzer (core Pub. 2)

// packages/ast-analyzer/src/extractor.ts
interface WorkloadFeatures {
  ioCallDensity: number;       // fetch/fs calls per LOC
  asyncDepth: number;          // max await nesting
  cpuLoopDensity: number;      // for/while loops per LOC
  stringTemplateRatio: number; // template literals / total strings
  nativeModuleCount: number;   // fs, crypto, child_process imports
  promiseChainLength: number;  // max .then() chain depth
}
 
function extractFeatures(sourceCode: string): WorkloadFeatures
function predictRuntime(features: WorkloadFeatures): 
  { runtime: 'bun' | 'deno' | 'node', confidence: number, reasoning: string }

Koszt: 3–4 tygodnie (AST parsing jest dobrze wspierany przez Babel/Acorn)

6.3 Priorytet 3: ERS Core Scheduler (Pub. 3)

Minimalny scheduler w Go (~800 LOC):

// internal/scheduler/scheduler.go
type Decision struct {
    Runtime     string  // "bun" | "deno" | "node"
    KeepAliveTTL time.Duration
    CarbonScore float64
    Reasoning   string
}
 
func (s *Scheduler) Schedule(fn *Function, signal CarbonSignal) Decision
func (s *Scheduler) RecordOutcome(fn *Function, energy float64)  // feedback

Koszt: 6–8 tygodni (najtrudniejszy komponent)


7. Szacowanie nakładu pracy i timeline

Rozszerzenie Pub. 1 (wersja dysertacyjna)

ZadanieNakładPriorytet
Dodanie LLRT do eksperymentów (#JE-EXP-7)2 tyg.Wysoki
Dodanie EdgeJS (następca WinterJS) — jeśli stabilny HTTP API1 tyg.Niski (bonus)
Platforma ARM (P3) — jeśli dostęp3–4 tyg.Wysoki (teza!)
Nowe workloady: SQLite, Crypto1 tyg.Średni
Rozbudowa literature review (+10 prac)2 tyg.Wysoki
Łącznie Pub. 1 rozszerzona~8–10 tyg.

Publikacja 2

ZadanieNakładPriorytet
Dataset 200+ funkcji serverless (zbieranie + labelowanie)4–5 tyg.Krytyczny
Implementacja AST Analyzer3 tyg.Krytyczny
Eksperymenty energetyczne (labelowanie)2 tyg.Krytyczny
Trening i ewaluacja ML modeli2 tyg.Krytyczny
Pisanie artykułu4 tyg.
Łącznie Pub. 2~15 tyg.

Publikacja 3

ZadanieNakładPriorytet
Platforma testowa (containerd + scheduler)6 tyg.Krytyczny
ERS Core Scheduler implementacja6 tyg.Krytyczny
Integracja Carbon API1 tyg.
Eksperymenty ewaluacyjne (20 funkcji × 3 baseline)4 tyg.
Pisanie artykułu5 tyg.
Łącznie Pub. 3~22 tyg.

Pisanie dysertacji

ZadanieNakład
Rozbudowa wstępu + lit. review (dysertacja)4 tyg.
Integracja rozdziałów Pub. 1–33 tyg.
Dyskusja syntetyczna + wnioski2 tyg.
Łącznie dysertacja~9 tyg.

Całkowity szacunek: ~54 tygodni (ok. 13 miesięcy intensywnej pracy)


8. Najważniejsze nowe hipotezy (do weryfikacji)

Z rozszerzenia Pub. 1

IDHipotezaMetoda weryfikacji
H-EXT-1LLRT jest energooszczędniejsze od Node.js o > 40% przy E_cold, ale gorsze o > 30% przy E_ss dla N > 50 wywołańEXP-7: LLRT vs {Node, Bun} na workloadzie CPU-bound
H-EXT-2Na ARM AArch64, przewaga Bun vs Node.js przy I/O-bound spada z 74% do < 40%EXP-8: P3 (Ampere/Graviton) — replikacja EXP-1
H-EXT-3JavaScriptCore ma najniższy próg amortyzacji JIT na ARM ze względu na optymalizacje AArch64 (N < 50 vs N ≈ 100 na x86-64)EXP-8: krzywe JIT amortyzacji na P3
H-EXT-4Bun z wbudowanym SQLite zużywa ≥ 25% mniej energii vs Node.js z better-sqlite3 dla 1000 prostych SELECT’ówEXP-9: nowy workload bazodanowy

Z Pub. 2

IDHipotezaMetoda weryfikacji
H-P2-1Gęstość wywołań I/O (I/O call density) i głębokość async są wystarczającymi cechami do klasyfikacji workloadu z F1 > 0,80Klasyfikator na zbiorze 200+ funkcji
H-P2-2Predykcja statyczna (bez uruchomienia) optymalnego runtime osiąga accuracy > 75%Cross-validation na zbiorze testowym
H-P2-3Online profiling (N=10 wywołań) poprawia predykcję do > 95%A/B test: static vs dynamic prediction

Z Pub. 3

IDHipotezaMetoda weryfikacji
H-P3-1ERS redukuje energię platformy o > 20% vs static Node.js baseline7-dniowy test na bare-metal z 25 funkcjami
H-P3-2Carbon-aware policy redukuje emisję CO₂ o > 10% w oknie 30-dniowymSymulacja z historycznymi danymi carbon intensity dla DE/PL
H-P3-3Overhead ERS schedulera < 2 ms na decyzjęBenchmark schedulera (1000 decyzji/s)
H-P3-4LACE-RL z empirycznym λ_idle=0,20 skraca całkowity czas utrzymania instancji o > 15% vs statyczny TTL=600sSymulacja traffic Poisson z parametrami z rzeczywistych danych

9. Ryzyka i alternatywy

Ryzyko 1: Brak dostępu do serwera ARM

Ryzyko: Platforma ARM (Ampere Altra) może być niedostępna w uczelni.
Mitygacja: AWS Graviton3 przez AWS Academy / research credits (gratis dla doktorantów). Fallback: Raspberry Pi 5 (Cortex-A76) — tańszy, ale mniejszy TDP; wyniki mniej reprezentatywne dla cloud.

Ryzyko 2: LLRT lub EdgeJS może zniknąć lub zmienić się znacznie

Ryzyko: Amazon LLRT jest wciąż w early preview (2024), może być porzucony. EdgeJS jest nowym projektem (następca porzuconego WinterJS — Shopify zaprzestał utrzymania WinterJS na rzecz EdgeJS).
Kontekst WinterJS → EdgeJS: WinterJS był runtime Shopify oparty na SpiderMonkey. Projekt nie jest utrzymywany — commits zatrzymały się, README odsyła do EdgeJS (https://edgejs.org/) jako aktywnego następcy. WinterJS NIE jest już opcją badawczą.
Mitygacja dla LLRT: Bun 2.x i Deno 3.x mogą zmienić profil energetyczny — to okazja na “longitudinal study”. QuickJS (silnik LLRT) jest stabilny i open-source niezależnie od Amazon.
Mitygacja dla EdgeJS: Traktować jako “bonus runtime” (niski priorytet), nie jako filar Pub. 1-ext. Monitorować GitHub aktywność przed inwestycją czasu.

Ryzyko 3: ML classifier Pub. 2 ma za niską accuracy

Ryzyko: Statyczne cechy AST mogą nie być wystarczające dla mixed workloadów.
Mitygacja: Przejście na dynamic profiling (pierwsze N wywołań) jako główny wkład, statyczne jako “przyśpieszenie” — to nadal novelty.

Ryzyko 4: ERS Pub. 3 zbyt ambitny implementacyjnie

Ryzyko: Budowa platformy serverless to dużo kodu poza domeną badawczą.
Mitygacja (własny dispatcher): Opcja A z Sekcji 5 (minimalny process pool, ~350 LOC Go) jest realnym rozmiarem projektu na 2–3 tygodnie implementacji. Nie wymaga znajomości Kubernetes.
Mitygacja (Nuclio): Jeśli izolacja jest wymagana przez recenzentów — Nuclio standalone z zewnętrznym ERS schedulem przez REST API. Nakład: ~200 LOC ERS + konfiguracja Nuclio (1–2 dni).
Nie rekomendujemy OpenFaaS dla tego projektu: OpenFaaS wymaga dodatkowego operatora lub faasd, community przesuwa się w stronę modelu enterprise, i nie oferuje czystego custom runtime hook bez konteneryzacji.


10. Wkłady artykułowe do dysertacji — mapa

Pub. 1 (DONE, Minor Revision):
  "Energy Efficiency of JavaScript Runtime Environments in Serverless Computing"
  → CCGrid'27 / IGSC'27 / Middleware'27
  → Wkład: pomiar, protokół, TOPSIS, JIT, cross-platform

Pub. 1-ext (rozszerzenie wersji dysertacyjnej):
  Dodaje: LLRT, EdgeJS (następca porzuconego WinterJS), ARM, SQLite workload, kompatybilność WinterTC
  → NIE osobna publikacja — to jest Rozdział 4 dysertacji

Pub. 2 (nowa):
  "Workload-Aware Runtime Selection for Energy-Efficient JavaScript Serverless Functions"
  → ICSE'28 / FSE'27 (Artifact track: js-energy-profiler CLI)
  → Wkład: dataset 200+ funkcji, AST classifier, online profiling

Pub. 3 (nowa, systems):
  "ERS: Energy-Runtime Scheduler for Carbon-Aware JavaScript Serverless Platforms"
  → SoCC'27 / EuroSys'28 / ATC'27
  → Wkład: open-source scheduler, carbon-aware policy, 20% energy reduction

11. Następne kroki (konkretne)

W ciągu 2 tygodni

  • Zainstalować LLRT w środowisku pomiarowym: curl -L https://github.com/awslabs/llrt/releases/latest/download/llrt-linux-x64.zip | unzip
  • Uruchomić EXP-7 na workloadach CPU-bound i cold-start (ten sam protokół co EXP-1)
  • Zbadać dostępność ARM — AWS Academy credits lub uczelniany klaster

W ciągu miesiąca

  • Zebrać 50 funkcji serverless z GitHub (tag: serverless-function, faas, aws-lambda) jako zalążek datasetu Pub. 2
  • Zaimplementować ast-analyzer w wersji 0.1 (Babel parser + 6 podstawowych cech)
  • Zaimplementować szkielet Minimal Process Pool Manager w Go (Opcja A dla ERS) — uruchomić 3 runtimes przez HTTP proxy
  • Alternatywnie: zbadać Nuclio standalone mode jako bazę ERS (zamiast OpenFaaS)

W ciągu kwartału

  • Złożyć rozszerzoną Pub. 1 (z LLRT + ARM jeśli dostępne) do CCGrid’27 lub IGSC’27
  • Mieć dataset 200 funkcji + wyniki energetyczne jako proof-of-concept Pub. 2
  • Zdefiniować architekturę ERS (ADR document) + pierwsza demo na 5 funkcjach

12. Rekomendacja: co robić jako pierwsze

Ścieżka minimalna (gwarantuje dysertację, 2 publikacje):

  1. Rozszerz Pub. 1 o LLRT + 2 nowe workloady + ARM (jeśli dostępne) → Pub. 1-final
  2. Zbuduj AST classifier + dataset 200 funkcji → Pub. 2
  3. ERS jako własny Process Pool Manager (~350 LOC Go) lub Nuclio standalone plugin → Pub. 3 (lżejsza, czystsze pomiary niż OpenFaaS)

Ścieżka ambitna (3 silne publikacje, ryzyko przekroczenia czasu):

  1. j.w. + pełna platforma ERS z carbon-aware + 30-dniowe testy
  2. Cel: EuroSys / SoCC (wysoko punktowane)

Rekomendacja: Zacznij od ścieżki minimalnej. ERS jako własny Process Pool Manager (~350 LOC Go) jest czystszym rozwiązaniem niż OpenFaaS (brak zanieczyszczenia RAPL przez Kubernetes overhead) i wciąż unikalnym wkładem badawczym. Nuclio standalone jako opcja jeśli recenzenci wymagają “istniejącej platformy” jako bazy porównania.


Dokument roboczy — aktualizować przy każdym kamieniu milowym.
Wygenerowano: 2026-05-29