Skip to content

fix: bound polling loop timeouts by remaining deadline time#216

Merged
edburns merged 5 commits into
mainfrom
copilot/fix-review-comment-3268776043
May 19, 2026
Merged

fix: bound polling loop timeouts by remaining deadline time#216
edburns merged 5 commits into
mainfrom
copilot/fix-review-comment-3268776043

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 19, 2026


Before the change?

  • Polling loops in testShouldGetLastSessionId and testShouldGetSessionMetadataById used a fixed 30s timeout per Future.get() call inside a loop with a 10s deadline. If the RPC stalled, a single iteration could block 3× longer than the intended overall deadline.

After the change?

  • Each iteration computes remaining = Math.max(1, deadline - currentTimeMillis()) and passes it as the per-iteration timeout, ensuring the overall wait is bounded by the 10s deadline:
long remaining = Math.max(1, deadline - System.currentTimeMillis());
lastId = client.getLastSessionId().get(remaining, TimeUnit.MILLISECONDS);

Pull request checklist

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)
  • mvn spotless:apply has been run to format the code
  • mvn clean verify passes locally

Does this introduce a breaking change?

  • Yes
  • No

edburns and others added 2 commits May 19, 2026 11:43
…ssionMetadataById

The Copilot CLI persists session state asynchronously, so querying
session metadata or the last session ID immediately after sendAndWait()
is a race condition. On Linux (CI) and Windows the I/O completes fast
enough to mask the issue, but on macOS the tests fail consistently.

Align the Java tests with the .NET and Node.js reference implementations:

- testShouldGetLastSessionId: close the session before calling
  getLastSessionId() (matches .NET DisposeAsync-then-query pattern),
  and poll with a 10-second deadline and 50ms intervals (matches
  Node.js client_lifecycle.e2e.test.ts polling pattern).

- testShouldGetSessionMetadataById: poll getSessionMetadata() with a
  10-second deadline and 50ms intervals until it returns non-null
  (matches .NET WaitForConditionAsync pattern).

Signed-off-by: Ed Burns <edburns@microsoft.com>
Copilot AI and others added 2 commits May 19, 2026 18:52
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
… deadline

The 10s polling deadline in testShouldGetLastSessionId and
testShouldGetSessionMetadataById was not actually enforced because each
iteration could block up to 30s on the Future.get() call. Now each
iteration uses Math.max(1, deadline - currentTimeMillis) as the timeout
so the overall wait is bounded by the intended 10s deadline.

Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix code based on review comment 3268776043 fix: bound polling loop timeouts by remaining deadline time May 19, 2026
Copilot AI requested a review from edburns May 19, 2026 18:54
@edburns edburns marked this pull request as ready for review May 19, 2026 19:02
Copilot AI review requested due to automatic review settings May 19, 2026 19:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates two polling-based tests in CopilotSessionTest so that per-iteration Future.get() timeouts are bounded by the remaining overall deadline, preventing a single stalled RPC from blocking longer than intended.

Changes:

  • Replaced fixed per-iteration Future.get(30s) timeouts with remaining-based timeouts against a 10s deadline.
  • Added polling loops (with short sleeps) for getLastSessionId() and getSessionMetadata() to accommodate asynchronous persistence behavior.
Show a summary per file
File Description
src/test/java/com/github/copilot/sdk/CopilotSessionTest.java Bounds polling loop get() timeouts by remaining deadline time for last-session-id and session-metadata tests.

Copilot's findings

Comments suppressed due to low confidence (1)

src/test/java/com/github/copilot/sdk/CopilotSessionTest.java:870

  • Same issue as the getLastSessionId polling loop: get(remaining, ...) can throw TimeoutException when remaining becomes small (down to 1ms), causing a premature test failure instead of continuing to poll until the 10s deadline. Handle TimeoutException inside the loop (retry until deadline) and consider capping the per-iteration timeout to avoid ultra-short timeouts near the end.
            long deadline = System.currentTimeMillis() + 10_000;
            while (System.currentTimeMillis() < deadline) {
                long remaining = Math.max(1, deadline - System.currentTimeMillis());
                metadata = client.getSessionMetadata(sessionId).get(remaining, TimeUnit.MILLISECONDS);
                if (metadata != null) {
                    break;
                }
                Thread.sleep(50);
  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread src/test/java/com/github/copilot/sdk/CopilotSessionTest.java
…eout

Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
@edburns edburns merged commit 186c8c9 into main May 19, 2026
10 checks passed
@edburns edburns deleted the copilot/fix-review-comment-3268776043 branch May 19, 2026 20:22
edburns added a commit to github/copilot-sdk that referenced this pull request May 19, 2026
edburns added a commit to github/copilot-sdk that referenced this pull request May 19, 2026
edburns added a commit to edburns/copilot-sdk that referenced this pull request May 21, 2026
* On branch edburns/80-java-monorepo-add-01 Commence work on https://github.com/github/cnew file:   80-java-monorepo-add-01-remove-before-merge/20260512-prompts.md

- Commence practice of keeping running prompts for sharing and review.

new file:   80-java-monorepo-add-01-remove-before-merge/dd-2989727-move-java-to-monorepo-plan.md

- Document WIP plan for review.

* refine to get ready for plan review

* On branch edburns/80-java-monorepo-add-01 Put the plan first.
modified:   80-java-monorepo-add-01-remove-before-merge/dd-2989727-move-java-to-monorepo-plan.md

* On branch edburns/80-java-monorepo-add-01 github/copilot-sdk-partners#89
modified:   .github/CODEOWNERS

- Add row mapping `java` to `@github/copilot-sdk-java`.

modified:   80-java-monorepo-add-01-remove-before-merge/dd-2989727-move-java-to-monorepo-plan.md

- Fix reference.

new:        80-java-monorepo-add-01-remove-before-merge/20260513-prompts.md

- Today's prompts.

* test: verify gpg signing

* On branch edburns/80-java-monorepo-add-01
modified:   80-java-monorepo-add-01-remove-before-merge/20260513-prompts.md
modified:   80-java-monorepo-add-01-remove-before-merge/dd-2989727-move-java-to-monorepo-plan.md

- WIP Phase 0.

.github/workflows/java-publish-maven.yml
.github/workflows/java-publish-snapshot.yml

- Copy over from `copilot-sdk-java-00`.

80-java-monorepo-add-01-remove-before-merge/ghcpsp-90-gpg-key-archive.sh
80-java-monorepo-add-01-remove-before-merge/ghcpsp-90-gpg-key-import.sh

- Durable way to hand off the ability to publish to maven central. Currently resides with @edburns.

* Per github/copilot-sdk-partners#89 no per-language teams

* Update progress

* Define gh-pages as WONTFIX

* Branch protection

* new prompts

* Sync regexp changes

* ghcp-sp-95-branch-protection

* ghcp-sp-95-branch-protection

* Complete phase 0

* Start on dd-2998002

* Phase 1: .githooks and instructions

* test: verify gpg signing

* Fixes github/copilot-sdk-partners#95

* Branch protuction.

* Mark more completed

* Phase 1 plan

* Copy Java SDK source files into java/ directory

Copied from github/copilot-sdk-java: src/, pom.xml, config/,
scripts/codegen/, CHANGELOG.md, README.md, jbang-example.java,
.lastmerge, docs/adr/, mvnw, mvnw.cmd, .mvn/, .gitignore, test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update pom.xml to use local test harness instead of git clone

Since the Java SDK now lives inside the copilot-sdk monorepo,
point copilot.sdk.clone.dir at the monorepo root (../)
instead of cloning into target/. Remove the antrun git clone
execution entirely. Update SCM URLs to github/copilot-sdk.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Document need to restore the POM property updating

* Document copilot --yolo progress

* Ignore log files

* Copy over github/copilot-sdk-java#216

* Restore antrun git-clone mechanism and add missing codegen files

Revert pom.xml to preserve the git-clone-based test harness setup
(copilot.sdk.clone.dir = target/copilot-sdk/) instead of pointing at
the monorepo root. Add scripts/codegen/package-lock.json (pins
@github/copilot@1.0.49-3) and .gitignore that were missed in the
initial file copy.

* Prepare for Phase 2

* Add java-sdk-tests.yml adapted from build-test.yml

Creates the Java SDK test workflow for the monorepo with:
- Push/PR triggers on java/** and test/** paths
- OS matrix: ubuntu, macos, windows (matching other SDKs)
- JDK 17 (microsoft distribution) with Maven cache
- Node.js setup for E2E test harness
- spotless:check formatting gate (Linux only)
- javadoc:javadoc verification (Linux only)
- mvn clean verify (build + all tests including E2E)
- Surefire report upload on failure

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Java job to codegen-check.yml

- Add java/scripts/codegen/** and java/src/generated/** to path triggers
- Add java-codegen job that runs npx tsx java.ts from java/scripts/codegen/
- Checks for uncommitted changes in java/src/generated/ after running codegen

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add java-codegen-fix.md agentic workflow

Adapted from copilot-sdk-java codegen-agentic-fix.md with paths updated
for the monorepo structure (java/ prefix on all paths). The .lock.yml
could not be generated because gh aw compile timed out — it can be
compiled later when gh aw is available in an appropriate environment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Java tooling to copilot-setup-steps.yml

- Add JDK 17 (microsoft distribution) with Maven cache
- Add Java codegen npm cache-dependency-path
- Add Java codegen dependency install step
- Add java -version and mvn --version to verification

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Maven and Java codegen npm ecosystems to dependabot.yaml

- Add maven ecosystem entry for /java directory
- Add npm ecosystem entry for /java/scripts/codegen (codegen deps)
- Both use multi-ecosystem-group 'all' matching existing entries

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* execute phase 2

* Update java-sdk-tests.yml: address review concerns

- Add push path filter (java/**, test/**, workflow, actions)
- Remove OS matrix, run on ubuntu-latest only
- Set permissions: contents write, checks write, pull-requests write
- Use SHA-pinned actions (matching copilot-sdk-java source)
- Add persist-credentials: false on checkout
- Use .github/actions/setup-copilot for COPILOT_CLI_PATH
- Add COPILOT_GITHUB_TOKEN and COPILOT_CLI_PATH env vars to mvn verify
- Add JaCoCo badge generation (generate-java-coverage-badge.sh)
- Add JaCoCo badge PR creation (peter-evans/create-pull-request)
- Add java-test-report composite action for step summary
- Upload test results artifact on main branch for site generation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revert codegen-check.yml; create standalone java-codegen-check.yml

Reverts codegen-check.yml to its composition on main (no Java paths).
Creates java-codegen-check.yml adapted from the standalone repo's
codegen-check.yml with monorepo paths (java/ prefix, working-directory).
Updates java-codegen-fix.md to reference java-codegen-check workflow.

The java-codegen-fix.lock.yml could not be re-compiled because gh aw
is not responsive in this environment. Run 'gh aw compile java-codegen-fix'
to regenerate it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* copilot-setup-steps: pin gh-aw version and enable pre-commit hooks

- Replace curl|bash gh-aw install with pinned setup action
  (github/gh-aw@4d44d0e89 v0.73.0, version: v0.68.3)
- Add 'git config core.hooksPath .githooks' to enable the repo-root
  pre-commit hook (runs Spotless on java/src/ changes)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* dependabot: add ignore rules and groups for Java entries

- Add ignore rules for actions/github-script and github/gh-aw-actions
  to the github-actions entry (SHAs managed by gh aw compile)
- Add ignore for major version bumps on Maven dependencies (may drop
  Java 17 support or have breaking API changes)
- Use dedicated groups for Java: java-maven-deps and java-codegen-deps
  (separate from the monorepo-wide multi-ecosystem-group)
- Give Java entries their own schedule instead of multi-ecosystem-group

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Ready to test java-sdk-tests.yml

* Closer review of build-tests to java-sdk-tests.yml

* prepare for phase 01 review

* Clean up .gitignore

* remove job logs

* Upgrade to gh aw 0.74.4

* Fix mangled codegen-check.yml: restore proper formatting from main

* chore(java): remove src/site directory and all references

The Maven Site documentation infrastructure is not needed in the
monorepo per the resolution of copilot-sdk-partners#85.

Removes:
- java/src/site/ directory (markdown docs, site.xml, CSS, images)
- maven-resources-plugin site filter executions from pom.xml
- maven-site-plugin and doxia-module-markdown dependency from pom.xml
- Entire <reporting> section from pom.xml
- Cookbook link from README.md
- Cookbook version-update step from java-publish-maven.yml workflow
- src/site/markdown walk from DocumentationSamplesTest

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove spurious file, caught by @stephentoub

* On branch edburns/80-java-monorepo-add-phase-01
modified:   .github/workflows/java-publish-maven.yml
modified:   .github/workflows/java-publish-snapshot.yml

@stephentoub wrote:

> Isn't the cwd at this point the root of the repo? If so do these CHANGELOG.md, README.md, jbang-example.java files not need to be further qualified to the java subdirectory?

Fixed. But in fairness, the publish workflows are set to be fully migrated in a subsequent phase. So I would have caught this later, by necessity. Even so, it's great to fix it as early as possible.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants