[Java] Add headers provider - #524
Conversation
Signed-off-by: danilo-najkov-db <danilo.najkov@databricks.com>
a2da75a to
9a9db35
Compare
…rovider Signed-off-by: danilo-najkov-db <danilo.najkov@databricks.com> # Conflicts: # java/NEXT_CHANGELOG.md # rust/jni/Cargo.toml
teodordelibasic-db
left a comment
There was a problem hiding this comment.
Mostly edge cases and races flagged by LLM.
Signed-off-by: danilo-najkov-db <danilo.najkov@databricks.com>
Signed-off-by: danilo-najkov-db <danilo.najkov@databricks.com>
Signed-off-by: danilo-najkov-db <danilo.najkov@databricks.com>
|
|
||
| #[async_trait] | ||
| impl HeadersProvider for JavaHeadersProvider { | ||
| async fn get_headers(&self) -> ZerobusResult<HashMap<&'static str, String>> { |
There was a problem hiding this comment.
A callback that exceeds recoveryTimeoutMs keeps running after the stream attempt times out. Tokio cannot cancel a spawn_blocking task once it has started, so dropping the future in rust/sdk/src/stream/grpc/connection.rs:80 leaves the Java call holding its worker and cloned GlobalRef. The next retry can start another callback, and repeated stream attempts can accumulate blocked workers and retained provider objects.
Could we serialize calls per provider and hold the guard inside the blocking closure, so cancellation cannot release it while the Java call is still running?
pub struct JavaHeadersProvider {
provider_ref: GlobalRef,
callback_lock: Arc<tokio::sync::Mutex<()>>,
}
let guard = Arc::clone(&self.callback_lock).lock_owned().await;
let provider_ref = self.provider_ref.clone();
tokio::task::spawn_blocking(move || {
let _guard = guard;
get_headers_blocking(provider_ref)
})
.awaitThis would not make a synchronous Java call cancellable, but it would keep one stuck provider adapter from consuming a new worker on every retry. A process-wide bounded executor would give a stronger global bound.
What changes are proposed in this pull request?
Adds custom HeadersProvider authentication to the Java SDK, matching the Rust stream-builder API.
Authentication Behavior
.oauth() and .headersProvider() are mutually exclusive. Calling either replaces the previously configured authentication method.
When the server rejects credentials, the SDK calls HeadersProvider.invalidate() before retrying so providers can clear cached tokens.
Testing