Skip to content

Replace 23 raw setTimeout calls in Logo engine with ManagedTimer#5799

Open
Ashutoshx7 wants to merge 1 commit intosugarlabs:masterfrom
Ashutoshx7:fix/zombie-timer-managed-cleanup
Open

Replace 23 raw setTimeout calls in Logo engine with ManagedTimer#5799
Ashutoshx7 wants to merge 1 commit intosugarlabs:masterfrom
Ashutoshx7:fix/zombie-timer-managed-cleanup

Conversation

@Ashutoshx7
Copy link
Contributor

@Ashutoshx7 Ashutoshx7 commented Feb 18, 2026

Problem

The Logo execution engine (js/logo.js) originally fired 23 raw setTimeout and setInterval calls for animation dispatch, note scheduling, and UI feedback — but none of these were cancelled when the user pressed Stop. The doStopTurtles() method simply set this.stopTurtle = true and nothing else. Every pending timer continued firing into the next run, living on as "Zombie Timers," which caused ghost animations, doubled audio, and stuck highlights.

Solution

Introduced a new ManagedTimer utility class (js/utils/ManagedTimer.js) that robustly tracks every timeout and interval, providing a single clearAll() kill switch.

  • All 23 raw setTimeout calls in logo.js are now replaced with managed and guarded variants (setGuardedTimeout).
  • The doStopTurtles() method now explicitly calls this._timerManager.clearAll() first — killing every pending timer instantly before they can execute.

Architecture Diagrams

BEFORE — Zombie Timers Survive Stop

image

AFTER — Clean Kill on Stop

image

Testing Performed

  • Browser Session: Confirmed that clicking "Stop" during heavy execution absolutely halts all animations and audio without bleeding into the background.
  • Diagnostic Logging: Verified that calling stop correctly forces window.activity.logo._timerManager.getStats() to report active: 0 alongside an increased cancelled metric.
  • ✅ 112/112 Jest test suites pass (3167 tests, 0 failures)
  • ✅ 55 new ManagedTimer unit tests passing.
  • ✅ 4 new Publisher.dataToTags unit tests passing.

@Ashutoshx7 Ashutoshx7 marked this pull request as ready for review February 18, 2026 21:35
@github-actions
Copy link
Contributor

✅ All Jest tests passed! This PR is ready to merge.

@Ashutoshx7 Ashutoshx7 force-pushed the fix/zombie-timer-managed-cleanup branch from 57e04bb to d09c22f Compare February 18, 2026 21:48
@github-actions
Copy link
Contributor

✅ All Jest tests passed! This PR is ready to merge.

@Ashutoshx7 Ashutoshx7 changed the title Replace 23 raw setTimeout calls in Logo engine with ManagedTimer… Replace 23 raw setTimeout calls in Logo engine with ManagedTimer Feb 21, 2026
… to prevent zombie timers

The Logo execution engine (js/logo.js) used 23 raw setTimeout/setInterval calls
for animation dispatch, note scheduling, and completion polling. When users hit
Stop, these timers were never cancelled — creating 'zombie timers' that continue
firing into the next run, causing ghost animations, doubled audio, and UI glitches.

Changes:
- Add js/utils/ManagedTimer.js (277 lines): centralized timer lifecycle manager
  with setTimeout, setGuardedTimeout, setInterval, setGuardedInterval, clearAll,
  and diagnostic getStats/resetStats methods
- Replace all 23 raw setTimeout calls in logo.js with managed/guarded variants
  that auto-cancel when the stop flag is set
- Wire ManagedTimer into RequireJS loader (js/loader.js) as a dependency of Logo
- Call timerManager.clearAll() at the top of doStopTurtles() so every pending
  timer is cancelled the instant the user presses Stop
- Harden Publisher.dataToTags with try/catch + Array.isArray guard for malformed
  project JSON, add module.exports for testability

Tests:
- 55 new tests for ManagedTimer (js/__tests__/ManagedTimer.test.js, 497 lines)
- 4 new tests for Publisher.dataToTags (planet/js/__tests__/Publisher.test.js)
- All 112 test suites pass (3167 tests, 0 failures)

Fixes zombie timer bug in the core execution engine.
@Ashutoshx7 Ashutoshx7 force-pushed the fix/zombie-timer-managed-cleanup branch from d09c22f to 6f2bcf3 Compare February 27, 2026 06:25
@github-actions
Copy link
Contributor

✅ All Jest tests passed! This PR is ready to merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant