Skip to content

feat(java): Add Auto Refresh - #13

Merged
alexr-bq merged 4 commits into
release-2from
auto-refresh-java-3aeb7883
Sep 23, 2026
Merged

alexr-bq merged 4 commits into
release-2from
auto-refresh-java-3aeb7883

Conversation

@alexr-bq

@alexr-bq alexr-bq commented Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add ElastiCacheIamAuthTokenManager for lazy token caching and background refresh.
  • Share a single token mint across concurrent callers and reuse cached tokens while valid.
  • Retry transient refresh failures with jittered exponential backoff while continuing to serve a valid token.
  • Complete shared refresh state on fatal failures and rethrow Errors so later token requests can recover.
  • Add token-change callbacks, credential-pair access, close semantics, and TokenRefreshException for operational failures.
  • Update the Lettuce example, Java documentation, changelog, and installed-artifact API coverage.

Verification

  • 42 Java unit tests passed.
  • Maven clean install, Javadocs, and dependency analysis passed.
  • Documentation examples compiled successfully.
  • Installed-artifact public API integration test passed.

@alexr-bq alexr-bq changed the title Auto refresh java feat(java): Add Auto Refresh Sep 16, 2026
@edlng

edlng commented Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator

could you set the base to point to #10 so its easier to view the diff? Or even better I think if you try the new Github stacked PRs feature, it will automatically have the base point back to main once #10 is merged

@alexr-bq
alexr-bq changed the base branch from release-2 to port-iam-authentication-to-java-a9f91d0a September 16, 2026 22:50
@alexr-bq
alexr-bq force-pushed the auto-refresh-java-3aeb7883 branch from 62dd1e6 to e6c14ef Compare September 16, 2026 22:54
@alexr-bq

Copy link
Copy Markdown
Collaborator Author

Done

@alexr-bq
alexr-bq added this pull request to stack #14 September 17, 2026 16:21
@alexr-bq
alexr-bq removed this pull request from stack #14 September 17, 2026 16:21
@alexr-bq
alexr-bq changed the base branch from port-iam-authentication-to-java-a9f91d0a to release-2 September 17, 2026 16:28
}
install(token, issuedAt);
refresh.complete(token);
} catch (RuntimeException exception) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This only catches RuntimeException, if provider.getToken() throws an Error (e.g. NoClassDefFoundError from a classpath mismatch), this catch doesn't fire and the future is never completed, so inFlight stays set and every later getToken() hangs in join(). On the executor thread it's also swallowed silently: ScheduledFuture captures it and we discard that future. Could we catch Throwable, complete the future exceptionally, and rethrow Errors?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed — refresh now catches Throwable, completes the shared future so inFlight is cleared, and rethrows Errors unchanged.

.build();
this.refreshAfterMillis = resolveRefreshAfterMillis(builder.refreshAfter);
this.onTokenChanged = builder.onTokenChanged;
this.callbackExecutor = builder.callbackExecutor == null

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One thing here, the callback runs on commonPool(), which the whole application shares (as few as one thread on a small host), and callbackExecutor isn't public, so a customer with a slow onTokenChanged (e.g. re-authenticating many connections) can stall unrelated work with no way to opt out.

We'd like all three languages to behave the same here: run the callback on the manager's own refresh thread, right after the token is installed and the lock is released, still off the caller's path, but on a thread we own. Suggestion: drop the executor and call onTokenChanged.accept(token) directly at the end of installAndComplete (outside synchronized), keep the try/catch, and note in the Javadoc that the callback should return quickly since it delays only the next refresh. Open to discuss this

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed. onTokenChanged now runs on the manager's own single refresh thread after the token is installed, the refresh is completed, and the lock is released.

@alexr-bq
alexr-bq merged commit 7d7f246 into release-2 Sep 23, 2026
12 checks passed
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