blog: the missing structured concurrency guarantees in k6's JavaScript runtime#1114
Open
blog: the missing structured concurrency guarantees in k6's JavaScript runtime#1114
Conversation
Document how @effectionx/k6 solves 20+ open k6 issues related to structured concurrency gaps: context loss, resource leaks, silent failures, unpredictable shutdown, and race conditions. References: - Sobek PR #115: grafana/sobek#115 - Effectionx PR #156: thefrontside/effectionx#156 Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
commit: |
Replace generic JS hook with k6-specific group/tag drift framing and align examples with k6 maintainer analysis in grafana/k6#2728. Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Remove absolution/blame-shift phrasing, make the two guarantees explicit, and keep maintainer discussion to paraphrase plus a single anchored quote. Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Restructure the post around: 1. The familiar k6 symptom (group/tag drift) 2. Why group() can't fix it (try/finally model + stack unwinding) 3. The two structured concurrency guarantees 4. Five categories of missing guarantees with issue links 5. Before/after example showing scope ownership 6. ECMAScript spec conformance and Sobek PR #115 7. What the conformance suite tests (what Sobek already has vs the one gap) 8. CTA for users and maintainers Voice: paraphrase + one anchored quote per section, neutral attribution, no absolution/blame-shift, explicit two guarantees. Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Reframe opening and key transitions around 'your expectations': - sync group() works the way you expect; async breaks that - structured concurrency aligns async with those expectations - scope owns async the same way it owns sync Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Update featured image to show async deforming the call stack: a then() callback runs on the next tick with restored tags, so group attribution changes. Add a short bridge paragraph tying the diagram to k6 tag behavior. Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Use "future tick" language consistently in the diagram and bridge paragraph. Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Explain that k6 reads current tags from the sync stack, but async callbacks run on a future tick after group() has unwound and restored tags. Session-ID: ses_39d99bc2ffeSKxHPZAk9P7E1O
Session-ID: w0t1p0:529AE7AB-BFCA-4B51-9880-FDF1D759DFBE
Session-ID: w0t1p0:529AE7AB-BFCA-4B51-9880-FDF1D759DFBE
- Cut 45-line GitHub issue list - Add bridge paragraph (universal async problem) - Combine technical sections - Tighten to ~650 words
- Replace fake delay() with http.asyncRequest() - Use until() instead of call() for promises - Rename section to 'Universal solution' - Clarify guarantees match sync expectations
- Add transition paragraph before code examples - Add 'Why Effection for k6?' section explaining polyfill design - Include Rosetta Stone link - Frame as easy/safe choice until JS runtime adds guarantees - Note additive adoption without Sobek changes beyond ECMAScript
- Replace abstract 'Lifetime is structural' with concrete code comparison - Rename Sobek section to 'Missing ECMAScript compliance' - Add link to conformance suite gist showing 80% compatibility - Link to ECMAScript spec for Generator.prototype.return - Show that only async cleanup was missing
- Replace incorrect npm install instructions with Docker-based setup - Redesign SVG to show vertical execution sequence with animated tag state - Left side shows async/await losing tags before .then() runs - Right side shows structured concurrency preserving tags through async - Animation highlights when tag state changes (the key insight)
- Left-align all headings - Update title: 'Missing Structured Concurrency Guarantees in Sobek' - Left-align step text (remove awkward centered comments) - Widen tag pills to fit 'group: coolgroup' text - Add result summary labels at bottom of each card - Fix card containers and spacing
- Remove CSS animations that caused content to be invisible on load - Make all content static and visible by default - Fix shadow filter bounds (use objectBoundingBox) - Adjust card heights to prevent overlap with result labels - Remove 'When the invariant holds, async stops lying' closing line (needs more thought, will revisit later)
- Fix animation by using proper keyframe timing - Steps appear sequentially over 8-second cycle - Left tag changes from green 'coolgroup' to red '(lost)' at step 4 - Right tag stays green 'coolgroup' through async, then '(done)' - Result summaries appear after all steps - Smooth loop with reset phase
- Add explicit audience callout for k6 users debugging flaky tests - Reference k6 issues #2848, #5435, #5249, #5524 as evidence of the pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a new blog post documenting how
@effectionx/k6solves structured concurrency problems in k6.Motivation
k6 has 20+ open issues that trace back to missing structured concurrency guarantees:
group()doesn't work with async calls (#2728, #2848)This post:
Related PRs
Checklist
www/AGENTS.mdconventionsdeno fmtapplied