[Improvement] Make GravitinoClient construction free of remote calls
- Dominant language
- Java
- Stars
- 3.2k
- Forks
- 935
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 298
Description
### What would you like to be improved?
`GravitinoClient`'s constructor performs remote calls: `loadMetalake(metalakeName)` runs directly in the constructor, and with the default `checkVersion` a version check is registered as a pre-connect handler. Both therefore execute with whatever credentials the `AuthDataProvider` resolves at construction time.
That is fine for a client built with fixed service credentials, but it behaves oddly for a shared client whose provider resolves the *caller* per request (the standalone Lance REST service does this after #12984):
- The client is created lazily on the first request, so the bootstrap calls run as whichever caller happens to arrive first. That caller must be able to load the metalake; later callers are never checked for it. The permission requirement lands non-deterministically on one arbitrary user.
- If the bootstrap fails, the field is left null, so every subsequent request retries the whole construction — one extra remote round trip per failing request until an authorized caller warms it.
- The failure surfaced to that first caller is a metalake load error rather than an error about the operation they actually requested.
### How should we improve?
Make the metalake handle lazy so constructing a `GravitinoClient` performs no remote call, and resolve it on first use (or per request) instead. Operations already go through the shared REST client, which resolves identity per request, so nothing else depends on the eager load.
This changes the timing of `NoSuchMetalakeException` for every caller of `GravitinoClient.builder(...).build()`, so it needs its own change with client tests updated, rather than riding along in a service-side PR.
Follow-up from the review of #12984.
Contributor guide
Assessment
This issue has not been assessed yet.