[dev] Remove sync-over-async where possible, consolidate blocking into helpers, add analyzers#1730
Merged
Merged
Conversation
…ult()) have been removed
…tly, but also more unique for searching
… 'could be async' code
Merged
4 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
This PR is a dev-targeting version of #1714 that reduces sync-over-async usage across Garnet (server, cluster, client, and tests), consolidates unavoidable blocking into a single helper, and adds analyzers/config to prevent regressions.
Changes:
- Introduces
AsyncUtils.BlockingWait(...)and replaces direct.Result/.GetAwaiter().GetResult()/.Wait()usage across the codebase where blocking is unavoidable. - Renames/rewrites many Task-returning APIs and background loops to follow async naming conventions (
*Async) and to useasync/awaitwithConfigureAwait(false)in library code paths. - Adds
Microsoft.VisualStudio.Threading.Analyzerspackage references and enables async naming analyzer rules in.editorconfig.
Reviewed changes
Copilot reviewed 93 out of 93 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| test/Garnet.test/TaskManagerTests.cs | Updates tests to use WaitAsync and async test methods |
| test/Garnet.test/RespVectorSetTests.cs | Converts recovery tests to async and switches commit waits to async |
| test/Garnet.test/RespSortedSetTests.cs | Uses CommitAOFAsync in AOF recovery tests |
| test/Garnet.test/RespHashTests.cs | Uses CommitAOFAsync in AOF recovery tests |
| test/Garnet.test/RespAofTests.cs | Converts AOF tests to async commit/wait APIs |
| test/Garnet.test/RespAofAzureTests.cs | Converts Azure AOF tests to async commit/wait APIs |
| test/Garnet.test/MultiDatabaseTests.cs | Uses CommitAOFAsync for multi-db AOF recovery tests |
| test/Garnet.test/GarnetJSON/JsonCommandsTest.cs | Uses CommitAOFAsync in JSON AOF recovery test |
| test/Garnet.test.cluster/ReplicationTests/ClusterReplicationBaseTests.cs | Converts manual checkpoint/commit test to async |
| modules/GarnetJSON/GarnetJSON.csproj | Adds VS Threading analyzers |
| metrics/HdrHistogram/Utilities/WriterReaderPhaser.cs | Removes sync-over-async; uses Thread.Yield/Sleep |
| metrics/HdrHistogram/HdrHistogram.csproj | Adds VS Threading analyzers |
| main/GarnetServer/GarnetServer.csproj | Adds VS Threading analyzers |
| libs/storage/Tsavorite/cs/src/core/Device/RandomAccessLocalStorageDevice.cs | Removes sync-over-async fast-path; awaits pooled handle acquisition |
| libs/server/TaskManager/TaskType.cs | Updates doc refs to renamed StoreWrapper task methods |
| libs/server/TaskManager/TaskManager.cs | Adds CancelAsync, removes sync Wait, and uses blocking helper where required |
| libs/server/StoreWrapper.cs | Converts checkpoint APIs to async; renames background tasks to *Async; removes sync commit helpers |
| libs/server/Servers/StoreApi.cs | Removes sync CommitAOF/WaitForCommit wrappers in favor of async APIs |
| libs/server/ServerConfig.cs | Blocks via helper on network thread for index growth; makes index resize handler async |
| libs/server/Resp/Vector/VectorManager.cs | Centralizes disposal blocking via AsyncUtils.BlockingWait |
| libs/server/Resp/Vector/VectorManager.Replication.cs | Refactors replication replay tasks to async/await and async shutdown |
| libs/server/Resp/RespServerSession.cs | Uses AsyncUtils.BlockingWait for network-thread AOF waits |
| libs/server/Resp/PubSubCommands.cs | Blocks on new ClusterPublishAsync from network thread |
| libs/server/Resp/Objects/SortedSetCommands.cs | Replaces .Result with AsyncUtils.BlockingWait on network thread |
| libs/server/Resp/Objects/ListCommands.cs | Replaces .Result with AsyncUtils.BlockingWait on network thread |
| libs/server/Resp/BasicCommands.cs | Suppresses async-suffix analyzer for NetworkGETAsync; removes ignored ConfigureAwait(false) on fire-and-forget |
| libs/server/Resp/AsyncProcessor.cs | Removes Task.Run wrapper; makes processor explicitly async |
| libs/server/Resp/AdminCommands.cs | Uses async checkpoint/commit APIs and blocks only on network thread via helper |
| libs/server/PubSub/SubscribeBroker.cs | Renames start loop to StartAsync |
| libs/server/Objects/ItemBroker/CollectionItemBroker.cs | Renames broker loop to StartAsync |
| libs/server/Metrics/GarnetServerMonitor.cs | Changes async void monitor loop to Task |
| libs/server/Garnet.server.csproj | Adds VS Threading analyzers |
| libs/server/Databases/SingleDatabaseManager.cs | Converts checkpoint and index-growth APIs to async/await patterns |
| libs/server/Databases/MultiDatabaseManager.cs | Converts checkpoint/index-growth to async; refactors AOF commit task aggregation |
| libs/server/Databases/IDatabaseManager.cs | Updates interface to async checkpoint/index growth methods |
| libs/server/Databases/DatabaseManagerBase.cs | Updates base class abstract API to async equivalents |
| libs/server/Cluster/IClusterProvider.cs | Changes publish forwarding API to ClusterPublishAsync |
| libs/server/Auth/Aad/IssuerSigningTokenProvider.cs | Uses centralized blocking helper for config retrieval |
| libs/server/AOF/AofProcessor.cs | Uses async checkpoint API but blocks in-place where required |
| libs/host/Garnet.host.csproj | Adds VS Threading analyzers |
| libs/host/Configuration/Options.cs | Removes sync-over-async endpoint creation; uses sync Format.TryCreateEndpoint |
| libs/common/Testing/ExceptionInjectionHelper.cs | Adds sync spin-yield helper WaitOnClear for DEBUG-only code |
| libs/common/Networking/TcpNetworkHandlerBase.cs | Removes async state-machine; returns base StartAsync task directly |
| libs/common/Networking/TaskToApm.cs | Uses centralized blocking helper and improves exception argument naming |
| libs/common/Networking/NetworkHandlerStream.cs | Renames internal read helper to ReadAsyncInternalAsync |
| libs/common/Networking/NetworkHandler.cs | Blocks for TLS client auth where required; uses blocking helper for completed reads |
| libs/common/LightClient.cs | Introduces sync socket connect path; removes sync-over-async connect |
| libs/common/Garnet.common.csproj | Adds VS Threading analyzers |
| libs/common/Format.cs | Splits endpoint creation into sync TryCreateEndpoint and async TryCreateEndpointAsync |
| libs/common/AsyncUtils.cs | Adds centralized blocking helpers for Task/ValueTask |
| libs/cluster/Session/RespClusterSlotManagementCommands.cs | Uses blocking helper for epoch transition on network thread |
| libs/cluster/Session/RespClusterReplicationCommands.cs | Converts replication initiation paths to async APIs; blocks only on network thread |
| libs/cluster/Session/RespClusterFailoverCommands.cs | Uses async epoch transition/replication-wait APIs with blocking helper on network thread |
| libs/cluster/Session/ReplicaOfCommand.cs | Renames network handler and blocks via helper for epoch/tasks on network thread |
| libs/cluster/Session/MigrateCommand.cs | Removes sync-over-async hostname resolve; uses async migrate start API with blocking helper |
| libs/cluster/Session/ClusterSession.cs | Makes epoch transition wait async; updates unsafe method signatures accordingly |
| libs/cluster/Server/Replication/ReplicationManager.cs | Updates resync and offset-wait APIs to async patterns |
| libs/cluster/Server/Replication/ReplicaOps/ReplicationReplicaAofSync.cs | Updates replica replay launch to new async task method |
| libs/cluster/Server/Replication/ReplicaOps/ReplicaReplayTask.cs | Converts async void replay task to Task and adds ConfigureAwait(false) |
| libs/cluster/Server/Replication/ReplicaOps/ReplicaReceiveCheckpoint.cs | Converts disk-based replicate initiation to async, avoids sync-over-async connect/commit waits |
| libs/cluster/Server/Replication/ReplicaOps/ReplicaDisklessSync.cs | Converts diskless replicate initiation to async, avoids sync-over-async connect/commit waits |
| libs/cluster/Server/Replication/ReplicaOps/ReceiveCheckpointHandler.cs | Replaces sync-over-async debug wait with WaitOnClear |
| libs/cluster/Server/Replication/PrimaryOps/ReplicationPrimaryAofSync.cs | Updates replica sync task entrypoint name to async |
| libs/cluster/Server/Replication/PrimaryOps/ReplicaSyncSession.cs | Renames checkpoint send APIs and async-ifies file/metadata send helpers |
| libs/cluster/Server/Replication/PrimaryOps/PrimarySync.cs | Converts attach/begin-sync APIs to async returning (success, error) |
| libs/cluster/Server/Replication/PrimaryOps/DisklessReplication/ReplicationSyncManager.cs | Renames and async-ifies diskless replication driver/flush APIs |
| libs/cluster/Server/Replication/PrimaryOps/DisklessReplication/ReplicationSnapshotIterator.cs | Uses centralized blocking helper for flush waits |
| libs/cluster/Server/Replication/PrimaryOps/DisklessReplication/ReplicaSyncSession.cs | Async-ifies flush pipeline; renames sync completion/AOF sync methods |
| libs/cluster/Server/Replication/PrimaryOps/AofSyncTaskInfo.cs | Renames replica AOF sync task entrypoint to async |
| libs/cluster/Server/Migration/MigrationDriver.cs | Converts slot-range ops and migration driver to async methods |
| libs/cluster/Server/Migration/MigrateSessionSlots.cs | Converts slots migration scan/transmit orchestration to async |
| libs/cluster/Server/Migration/MigrateSessionKeys.cs | Converts KEYS migration workflow (incl. deletion/config propagation) to async |
| libs/cluster/Server/Migration/MigrateSessionKeyAccess.cs | Converts config propagation wait to async API |
| libs/cluster/Server/Migration/MigrateSessionCommonUtils.cs | Converts record write/send and response handling to async helpers |
| libs/cluster/Server/Migration/MigrateSession.cs | Async-ifies connection/auth check and removes old sync slot-range helpers |
| libs/cluster/Server/Migration/MigrateOperation.cs | Converts migrate operation initialize/transmit routines to async |
| libs/cluster/Server/Gossip/Gossip.cs | Refactors publish forwarding and gossip loops to async helpers with partial sync fast-paths |
| libs/cluster/Server/Gossip/GarnetServerNode.cs | Uses ValueTask for initialization and refactors gossip to async/await |
| libs/cluster/Server/Gossip/GarnetClusterConnectionStore.cs | Renames connection store methods to *Async and uses ValueTask where appropriate |
| libs/cluster/Server/Gossip/GarnetClientExtensions.cs | Renames client extension APIs to *Async; updates publish span signatures |
| libs/cluster/Server/Failover/ReplicaFailoverSession.cs | Converts replica failover flow helpers to async and updates client calls |
| libs/cluster/Server/Failover/PrimaryFailoverSession.cs | Converts primary failover flow helpers to async and removes sync-over-async |
| libs/cluster/Server/Failover/FailoverManager.cs | Updates failover task entrypoints to renamed async methods |
| libs/cluster/Server/ClusterProvider.cs | Makes epoch transition wait async and updates cluster publish forwarding to async |
| libs/cluster/Server/ClusterManagerWorkerState.cs | Converts TryAddReplica to async, returning (success, error) |
| libs/cluster/Server/ClusterManager.cs | Renames background flush loop to async and starts it fire-and-forget |
| libs/cluster/Garnet.cluster.csproj | Adds VS Threading analyzers |
| libs/client/GarnetClientAPI/GarnetClientExecuteAPI.cs | Updates span parameter passing for no-response execute API |
| libs/client/GarnetClient.cs | Removes sync-over-async connect/auth; adds sync socket connect helper and blocks explicitly via AsyncUtils |
| libs/client/ClientSession/GarnetClientSession.cs | Refactors connect/reconnect to avoid sync-over-async; adds ConnectAsync |
| hosting/Windows/Garnet.worker/Garnet.worker.csproj | Adds VS Threading analyzers |
| Directory.Packages.props | Adds analyzer package version pin |
| .editorconfig | Enables VSTHRD200 async suffix rule as error and configures analyzer severities |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…duce IsAuthenticated(...) to allow polling for auth completion, which many callers assume
badrishc
approved these changes
Apr 28, 2026
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.
devtargeting version of #1714