Commit eb88b3b
Fix smart retry for structured message decoding with relative indexing and byte alignment (#47243)
* Initial plan
* Initial analysis of smart retry issue with structured message decoder
Co-authored-by: gunjansingh-msft <[email protected]>
* Implement smart retry fix for structured message decoding
The fix changes the retry strategy to restart downloads from the beginning
rather than trying to continue mid-stream, which is incompatible with the
structured message format that requires sequential parsing from the start.
Co-authored-by: gunjansingh-msft <[email protected]>
* Add unit tests for DecoderState with byte skipping
Co-authored-by: gunjansingh-msft <[email protected]>
* Update test expectations to match smart retry implementation
All retry requests now start from offset 0 for structured message validation
since the decoder must parse complete messages from the beginning.
Co-authored-by: gunjansingh-msft <[email protected]>
* Fix smart retry to properly track consumed encoded bytes
The original implementation tracked received buffer sizes before decoding,
which didn't account for pending bytes from previous buffers. This caused
retry offsets to be incorrect. Now tracking only newly consumed bytes
after accounting for pending data.
Co-authored-by: gunjansingh-msft <[email protected]>
* Revert test expectations and unused constants
Since smart retry now correctly resumes from interrupted offset (not from
beginning), reverted test expectations to validate progressive offsets.
Also removed unused DECODED_BYTES_TO_SKIP constant and unit tests that
were specific to the "restart from beginning" approach.
Co-authored-by: gunjansingh-msft <[email protected]>
* Fix byte tracking to count received bytes not consumed bytes
The issue was that totalEncodedBytesProcessed was tracking consumed bytes
(what the decoder processed), but it should track received bytes (what came
from the network). This ensures retry requests fetch new data after what
was already received, while the pending buffer holds unconsumed bytes.
On retry: request starts after all received bytes, decoder continues from
its internal state with pending bytes, new bytes appended after pending.
Co-authored-by: gunjansingh-msft <[email protected]>
* Fix retry offset calculation to use getRetryOffset() method
The critical bug was using getTotalEncodedBytesProcessed() for retry offset,
which includes pending bytes. This caused gaps in the byte stream when
combining pending + new data. The existing getRetryOffset() method correctly
subtracts pending bytes to get the actual file position where new data
should start, ensuring continuous byte streams across retries.
Co-authored-by: gunjansingh-msft <[email protected]>
* Track segment boundaries for smart retry resumption
Implemented segment boundary tracking in StructuredMessageDecoder:
- Added lastCompleteSegmentStart to track where complete segments end
- Changed messageOffset and segment fields to long for proper offset tracking
- Fixed segment size reading to handle unsigned long values correctly
- Updated DecoderState.getRetryOffset() to use segment boundaries
- Ensures retries resume from complete segment boundaries, not mid-segment
This matches the decryptor pattern where retries align with block boundaries.
Co-authored-by: gunjansingh-msft <[email protected]>
* Add debug logging for segment boundary tracking and retry offsets
Added verbose logging to track:
- Segment completion with byte offsets in StructuredMessageDecoder
- Retry offset calculation in DecoderState
- Retry range in BlobAsyncClientBase for structured messages
This helps diagnose smart retry behavior and verify segment boundary alignment.
Co-authored-by: gunjansingh-msft <[email protected]>
* Reset decoder and clear pending buffer on retry
Critical fix for smart retry:
- Added resetToLastCompleteSegment() to decoder to rewind messageOffset
- Call reset in getRetryOffset() to sync decoder state with retry offset
- Clear pending buffer since bytes after segment boundary will be re-fetched
- Ensures decoder's messageOffset matches the file position being requested
This prevents decoder from reading at wrong offsets after retry.
Co-authored-by: gunjansingh-msft <[email protected]>
* Add comprehensive diagnostic logging for smart retry debugging
Added detailed logging to track decoder state and buffer positions:
- readAndValidateSegmentLength() with hex dump of buffer contents
- Enhanced resetToLastCompleteSegment() logging with all state details
- Segment completion logging with offset and length details
- Buffer reception logging in decodeStream with pending/new byte counts
- Retry offset calculation logging with before/after decoder state
This will help identify where decoder state and retry offset become misaligned.
Co-authored-by: gunjansingh-msft <[email protected]>
* Fix byte alignment and endianness in decoder buffer handling
- combineWithPending: returns buffer with position=0 and LITTLE_ENDIAN
- updatePendingBuffer: allocates buffer with LITTLE_ENDIAN order
- decodeStream: proper position tracking for consumed bytes
- Added debug logging for decode iteration
Co-authored-by: gunjansingh-msft <[email protected]>
* Fix decodeStream with relative indexing for correct segment alignment
Implemented the correct algorithm for smart retry:
- Capture absoluteStartOfCombined before adding new bytes
- Calculate relativeIndex = decoderOffset - absoluteStartOfCombined
- Add peekNextSegmentLength to peek segment length without consuming
- Compute encodedSegmentSize = header + payload + CRC
- Slice complete segments only before decoding
- Update totalEncodedBytesProcessed after each segment is decoded
This ensures proper byte alignment and segment boundary handling.
Co-authored-by: gunjansingh-msft <[email protected]>
---------
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: gunjansingh-msft <[email protected]>1 parent 24a6aaf commit eb88b3b
File tree
3 files changed
+340
-64
lines changed- sdk/storage
- azure-storage-blob/src/main/java/com/azure/storage/blob/specialized
- azure-storage-common/src/main/java/com/azure/storage/common
- implementation/structuredmessage
- policy
3 files changed
+340
-64
lines changedLines changed: 7 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1407 | 1407 | | |
1408 | 1408 | | |
1409 | 1409 | | |
1410 | | - | |
1411 | | - | |
1412 | | - | |
1413 | | - | |
| 1410 | + | |
| 1411 | + | |
| 1412 | + | |
1414 | 1413 | | |
1415 | 1414 | | |
1416 | 1415 | | |
| 1416 | + | |
| 1417 | + | |
| 1418 | + | |
| 1419 | + | |
1417 | 1420 | | |
1418 | 1421 | | |
1419 | 1422 | | |
| |||
Lines changed: 152 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
| 30 | + | |
31 | 31 | | |
32 | | - | |
33 | | - | |
| 32 | + | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
39 | 43 | | |
40 | 44 | | |
41 | 45 | | |
| |||
45 | 49 | | |
46 | 50 | | |
47 | 51 | | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
48 | 96 | | |
49 | 97 | | |
50 | 98 | | |
| |||
79 | 127 | | |
80 | 128 | | |
81 | 129 | | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
82 | 215 | | |
83 | 216 | | |
84 | 217 | | |
| |||
90 | 223 | | |
91 | 224 | | |
92 | 225 | | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
93 | 229 | | |
94 | | - | |
95 | 230 | | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
| 231 | + | |
| 232 | + | |
100 | 233 | | |
101 | 234 | | |
102 | 235 | | |
| |||
126 | 259 | | |
127 | 260 | | |
128 | 261 | | |
129 | | - | |
130 | | - | |
| 262 | + | |
| 263 | + | |
131 | 264 | | |
132 | 265 | | |
133 | 266 | | |
| |||
182 | 315 | | |
183 | 316 | | |
184 | 317 | | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
185 | 327 | | |
186 | 328 | | |
187 | | - | |
188 | | - | |
189 | 329 | | |
190 | 330 | | |
191 | 331 | | |
| |||
0 commit comments