Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Remove per-message Task.Run from Service Bus inline message deserialization

クローズ
#1,376 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 3 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
74/100
issue の種類
リファクタリング
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
azure, csharp

調査の方向性

src/DurableTask.ServiceBus/Common/ServiceBusUtils.cs の LoadMessageStreamAsync から開始し、続いて ServiceBusOrchestrationService.cs のバッチ逆シリアル化の呼び出し箇所を確認します。両方のターゲット・フレームワーク分岐をカバーするテストを追加し、外部 blob の読み込みは変更しないまま、inline task がすでに完了していることを確認します。要求されたパフォーマンス指標を使い、デフォルトの prefetch サイズでのバッチ動作を比較します。

索引モデルが issue の本文から書いたものです。

説明

What is the issue

ServiceBusUtils.LoadMessageStreamAsync queues synchronous, in-memory work to the thread pool for every message whose body is stored inline:

https://github.com/Azure/durabletask/blob/5217032961abf45846f462732a5e2813316e3747/src/DurableTask.ServiceBus/Common/ServiceBusUtils.cs#L290-L307

For netstandard2.0, the work is only new MemoryStream(message.Body). For net48, message.GetBody<Stream>() reads the already-received brokered-message body. Neither branch performs asynchronous I/O, but both use Task.Run.

The orchestration and tracking receivers deserialize whole batches through this method using Task.WhenAll:

https://github.com/Azure/durabletask/blob/5217032961abf45846f462732a5e2813316e3747/src/DurableTask.ServiceBus/ServiceBusOrchestrationService.cs#L543-L561

https://github.com/Azure/durabletask/blob/5217032961abf45846f462732a5e2813316e3747/src/DurableTask.ServiceBus/ServiceBusOrchestrationService.cs#L1358-L1372

The configured prefetch count is 50, so a full batch can enqueue 50 trivial thread-pool work items at once:

https://github.com/Azure/durabletask/blob/5217032961abf45846f462732a5e2813316e3747/src/DurableTask.ServiceBus/Settings/ServiceBusOrchestrationServiceSettings.cs#L70-L73

Performance impact

Each inline message creates and schedules an unnecessary work item plus its task/delegate state. Under sustained load, batches from multiple dispatchers create bursts of thread-pool queueing that add scheduling latency, consume worker threads, and increase short-lived allocations. Thread-pool ramp-up or contention can amplify first-batch and tail latency even though there is no I/O to overlap.

The overhead scales with message rate and is paid before every inline task-message deserialization. The external-blob path is genuinely asynchronous and is not affected by this concern.

Proposed backward-compatible solution

Keep the existing private Task<Stream> signature and return an already-completed task for inline bodies:

#if NETSTANDARD2_0
return Task.FromResult<Stream>(new MemoryStream(message.Body));
#else
return Task.FromResult(message.GetBody<Stream>());
#endif

This preserves the same stream construction and downstream deserialization behavior while removing the thread-pool hop. Leave the blob-store load path unchanged.

Validation

  • Add coverage for both target-framework branches confirming that inline bodies deserialize identically and the returned task is already complete.
  • Retain integration coverage for external blob-backed messages.
  • Benchmark batch deserialization at the default prefetch size, comparing elapsed time, allocations, thread-pool work-item count, and tail latency.
主要言語
C#
スター
1.7k
フォーク
335
平均マージ
5日 3時間
マージ済み PR(30日)
8

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Azure/durabletask のほかの issue

Azure/durabletask の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。