Skip to content

Fix Await to process Go-scheduled jobs instead of blocking in js_std_loop#690

Merged
buke merged 4 commits intobuke:mainfrom
davidroman0O:main
Mar 15, 2026
Merged

Fix Await to process Go-scheduled jobs instead of blocking in js_std_loop#690
buke merged 4 commits intobuke:mainfrom
davidroman0O:main

Conversation

@davidroman0O
Copy link
Contributor

When using ctx.NewPromise with ctx.Schedule to resolve Promises from Go goroutines, the Await loop would block forever in js_std_loop because the C event loop doesn't know about Go's job queue.

This change replaces the js_std_loop call with cooperative polling that checks both Go jobs and JS jobs, yielding briefly between iterations. This allows async Go bridge functions to work correctly with Await.

The AwaitDrivesStdLoopForTimeout test was updated to use ctx.Schedule instead of setTimeout, since setTimeout depends on js_std_loop's internal timer handling which is no longer called.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical issue where the Await function would block indefinitely when JavaScript Promises were resolved by Go-scheduled jobs. The previous implementation relied on the C event loop (js_std_loop), which was unaware of Go's job queue. The solution introduces a cooperative polling mechanism within Await that actively processes both Go-scheduled jobs and JavaScript microtasks, ensuring that Promises initiated from Go goroutines are resolved correctly without causing the event loop to block.

Highlights

  • Await Mechanism Reworked: The Await function now employs a cooperative polling loop instead of blocking in js_std_loop, enabling it to process Go-scheduled jobs effectively.
  • Go Job Processing Integrated: ctx.ProcessJobs() is explicitly called within the Await loop to ensure that Go-scheduled work, such as promise resolutions originating from goroutines, is properly handled.
  • Idle Polling with Yield: When no JavaScript microtasks or Go jobs are immediately pending, the Await loop now briefly yields using time.Sleep(time.Millisecond) to prevent busy-waiting while awaiting external Go-scheduled work.
  • Test Case Updated: The AwaitDrivesStdLoopForTimeout test was refactored and renamed to AwaitDrivesScheduleForResolve to specifically validate the new Await behavior with ctx.Schedule instead of setTimeout.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • context.go
    • Imported the time package to support yielding in the Await loop.
    • Updated the Await function's documentation to describe the new polling-based implementation for processing Go-scheduled jobs.
    • Modified the Await loop to explicitly call ctx.ProcessJobs() at the beginning of each iteration and when no JavaScript microtasks are pending.
    • Replaced the call to C.js_std_loop with custom polling logic that checks for Go jobs, re-evaluates promise state, and introduces a time.Sleep for yielding when no immediate work is available.
  • context_test.go
    • Renamed the test AwaitDrivesStdLoopForTimeout to AwaitDrivesScheduleForResolve to better reflect its purpose.
    • Rewrote the test case to use ctx.NewPromise and ctx.Schedule to simulate a promise resolved from a Go goroutine, verifying the new Await behavior.
    • Updated the expected result string to match the new test logic.
Activity
  • No activity (comments, reviews, progress) was provided for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively resolves a blocking issue in Await by replacing the call to js_std_loop with a cooperative polling mechanism. This new approach correctly processes jobs scheduled from Go, allowing asynchronous operations to resolve promises without deadlocking the event loop. The logic appears sound, and the accompanying test case has been appropriately updated to validate the fix. I have one minor suggestion to improve code maintainability.

context.go Outdated
if ctx.jobQueue != nil && len(ctx.jobQueue) > 0 {
continue // more Go jobs to process
}
time.Sleep(time.Millisecond)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The polling interval time.Millisecond is used here as a magic number. It's recommended to define this as a named constant at the package level (e.g., const awaitPollingInterval = time.Millisecond). This improves readability by giving the value a clear semantic name and makes it easier to configure or update in the future.

References
  1. Avoid using magic numbers (unnamed numerical constants) directly in code. Instead, define them as named constants to improve readability, clarity, and maintainability. This makes the purpose of the value explicit and simplifies future modifications.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the change you asked for

@codecov
Copy link

codecov bot commented Mar 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (b8d50de) to head (5ba376f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #690   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           11        11           
  Lines         2349      2355    +6     
=========================================
+ Hits          2349      2355    +6     
Files with missing lines Coverage Δ
context.go 100.00% <100.00%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b8d50de...5ba376f. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- the nil check on ctx.jobQueue at line 1056 is redundant since len() on a nil channel returns 0
- more coverage
@davidroman0O
Copy link
Contributor Author

It was funny to make a PR with agents

@buke buke merged commit 2e9e3fa into buke:main Mar 15, 2026
8 checks passed
@buke
Copy link
Owner

buke commented Mar 15, 2026

thanks

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.

2 participants