NativeScript / NativeScript/ios
worker.terminate() is a no-op during entry evaluation, and terminating there wedges teardown
Personne n'a encore pris cette issue.
- Langage dominant
- JavaScript
- Étoiles
- 150
- Forks
- 43
- Merge moyen
- 3 j 10 h
- PR mergées (30 j)
- 22
Description
Found while completing #443's pump-termination item (three empirical rounds on the #444 branch); target semantics below are verified on Android, where terminate-during-entry works (android#2021 @ 351bef64, spec-proven with terminate landing 0-1ms into the entry body).
The defect (iOS)
The no-op: WorkerWrapper::workerIsolate_ is assigned only after the background looper's func() returns — and func() is where entry evaluation (the pumped module-graph load, any top-level-await park) runs. Terminate() bails on the null isolate, so for a worker still inside its entry, worker.terminate() does nothing: no TerminateExecution, no termination-requested flag. The pump bails landed in #444 engage only once the worker has a published isolate — the parked-entry scenario #443's pump item describes is unreachable on iOS for this reason.
The wedge: publishing the isolate early (via a separate atomic, drain-guard semantics untouched) makes Terminate() genuinely fire mid-entry — and the suite then hangs past 600s in teardown. That attempt was reverted on #444's branch: shipping it would convert a silent no-op into a hang. The comment at WorkerWrapper.mm (Terminate) records the gap at the site.
Target semantics — what correct terminate-during-entry looks like
Verified end-to-end on Android (trace + spec); the fix here must satisfy all six:
- Prompt pump exit via a termination-requested flag, not the V8 probe alone —
IsExecutionTerminatingis a mid-unwind probe and a parked pump runs no JS. (Already converged: android e11c9c30 / iOS's requested-flag in #444; iOS's flag is currently unreachable mid-entry because of the no-op above.) - Termination never masquerades: the evaluator checks termination BEFORE its timeout branch (never "Top-level await timed out"), and exception construction has an explicit HasTerminated/empty-Message branch (never an entry rejection with a fabricated message).
- No onerror on a dying worker: the error router early-returns on the wrapper's terminating flag — a terminated entry produces neither worker-scope
onerrornor a parent error event. Terminate is not an error. - Everything after the bail runs no JS and tolerates empty answers: the settle-gate's capability re-
Evaluate()returns empty on a terminating isolate and must fall through inertly; the teardown chain drops loop entries and releases handles only, never consuming an unchecked Maybe beforeDispose. - Error-report building must be termination-safe: anything between the bail and disposal that formats messages/stacks must read through
FromMaybe/IsEmpty, neverToChecked/ToLocalChecked— the termination interrupt can materialize inside the reporter itself (ToDetailStringruns JS). Android hit exactly this CHECK-abort and fixed it in 351bef64; iOS's exception/message formatters need the same audit as part of this work. - The window is real, not theoretical: on Android the spec's terminate landed 0-1ms into the entry body on every iteration. Any fix must be spec-proven with the same shape (worker .mjs entry parked in TLA, terminated mid-pump, repeated iterations).
Scope
A worker-lifecycle design pass: early isolate publication paired with a teardown path that tolerates termination landing inside entry evaluation (the pumped graph load, the TLA park, and the queue-arm-before-isolate window are all live during func()), plus the rule-5 formatter audit. Cross-runtime contract: the six rules above should hold identically on both platforms; Android already conforms.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par l’implémentation de Terminate et son commentaire dans WorkerWrapper.mm, puis comparez le comportement d’iOS avec les modifications e11c9c30 et 351bef64 d’Android. Suivez l’évaluation de l’entrée, le graphe de modules pompé, la mise en attente de TLA, l’évaluation du settle-gate, le démontage, ainsi que le formatage des exceptions et des messages. Le travail est terminé lorsque les six règles de terminaison énoncées sont respectées sur les deux plateformes et que des tests de spécification répétés terminent une entrée .mjs mise en attente au milieu du pompage.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- javascript
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 25/100