Repository navigation
Add blocking (non-async) API wrapping the async API [prototype] - #837
Open
John Batty (johnbatty) wants to merge 1 commit into
Open
John Batty (johnbatty) wants to merge 1 commit into
John Batty (johnbatty) wants to merge 1 commit into
Conversation
Each module now has a generated `blocking` submodule (behind the new `blocking` feature) with a Client and ClientBuilder that wrap the async client, running each request on a hidden tokio runtime. All credential types, retry options and pipeline policies are supported. Using the blocking API from within an async runtime returns an error. Request builders now have a send mode type parameter (defaulting to async), which selects between the async and blocking send(). See microsoft#835. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a blocking (non-async) API that wraps the existing async API, as requested in #835. Each request runs on a hidden tokio runtime, so the blocking
API supports everything the async API does: all credential types (PAT, OAuth/
TokenCredential, Azure CLI), retry options, and pipeline policies.It's opt-in (the
blockingfeature) and additive: existing async code compiles unchanged, and default builds are unaffected.Addresses #835.
Design
blockingsubmodule containingClient,ClientBuilderand a client peroperation group.
blocking::ClientBuilderwraps the asyncClientBuilderand supports all of its options: endpoint, scopes, retry, transport, per-call/per-trypolicies.
blocking::Client::from(async_client)converts an existing async client.RequestBuilder<M = ()>, held as a zero-sizedPhantomData<M>.(), the default, is async. Code that nameslist::RequestBuilderis unaffected, and.await/IntoFuturework as before.blocking::Blockingis for builders created by a blocking client. These have only a blockingsend(), so the compiler rejects any attempt to.awaita blocking request.send_future(). The asyncsend()returns it, and theblocking
send()runs it on the hidden runtime. Requests are identical either way.src/blocking.rs): a single tokio runtime shared by all blocking clients, created on first use, with one worker thread soconnections keep being serviced between requests. It works when blocking clients are used from several threads at once.
send()from within an async runtime returns an error instead of panicking.Limitations
artifacts_downloadis async-only.wasm32.Breaking changes
RequestBuildertypes have a new mode type parameter. It defaults to async, so code that names the type is unaffected.Code generator changes (
autorust)RunConfig.generate_blocking(set inado-autorust/src/main.rs) turns on blocking client generation.modules.
implblock.Cost
Measured on
azure_devops_rust_apiwith--all-features:cargo checkThe
cargo checkdifference is within run-to-run noise. The larger release-build increase is probably because each operation's async code is compiledfor both modes; this hasn't been confirmed. Builds without the
blockingfeature don't compile the blocking clients.The
blockingfeature adds no crates to the dependency tree (135 withgiteither way); it only enables tokio'srt-multi-threadfeature.Other changes
git_repo_list_blockingwit_work_item_create_blocking(a JSON Patch body)tests/blocking.rs: tests against a local mock HTTP server:Basicauth, and theUser-Agentset by the azure_core pipelineHttpResponseerrorTokenCredentialproduces aBearerheaderFromcargo test --all-features, so the new tests run.CLAUDE.mdandSKILL.mdupdates.Testing
./build.shreproduces the committed generated code.cargo fmt --checkand clippy with--deny warningspass: all features (library and examples),git,git,blockingandcore,blocking.cargo testpasses with default features and with--all-features.cargo doc --all-featurespasses, with no new warnings.🤖 Generated with Claude Code