2
2
// Licensed under the MIT license.
3
3
4
4
using System ;
5
- using System . Diagnostics ;
5
+ using System . Threading ;
6
+ using Microsoft . Extensions . Logging ;
6
7
7
8
namespace Tsavorite . core
8
9
{
@@ -65,8 +66,6 @@ internal void StreamingSnapshotScanPhase1()
65
66
{
66
67
try
67
68
{
68
- Debug . Assert ( systemState . Phase == Phase . PREP_STREAMING_SNAPSHOT_CHECKPOINT ) ;
69
-
70
69
// Iterate all the read-only records in the store
71
70
scannedUntilAddressCursor = Log . SafeReadOnlyAddress ;
72
71
var scanFunctions = new ScanPhase1Functions ( streamingSnapshotIteratorFunctions , _hybridLogCheckpointToken , _hybridLogCheckpoint . info . version , _hybridLogCheckpoint . info . nextVersion ) ;
@@ -75,9 +74,17 @@ internal void StreamingSnapshotScanPhase1()
75
74
_ = s . ScanCursor ( ref cursor , long . MaxValue , scanFunctions , scannedUntilAddressCursor ) ;
76
75
this . numberOfRecords = scanFunctions . numberOfRecords ;
77
76
}
77
+ catch ( Exception e )
78
+ {
79
+ logger ? . LogError ( e , "Exception in StreamingSnapshotScanPhase1" ) ;
80
+ throw ;
81
+ }
78
82
finally
79
83
{
80
- Debug . Assert ( systemState . Phase == Phase . PREP_STREAMING_SNAPSHOT_CHECKPOINT ) ;
84
+ // We started this task before entering PREP_STREAMING_SNAPSHOT_CHECKPOINT, so we
85
+ // need to wait until the state machine is in PREP_STREAMING_SNAPSHOT_CHECKPOINT
86
+ while ( systemState . Phase != Phase . PREP_STREAMING_SNAPSHOT_CHECKPOINT )
87
+ Thread . Yield ( ) ;
81
88
GlobalStateMachineStep ( systemState ) ;
82
89
}
83
90
}
@@ -120,14 +127,10 @@ internal void StreamingSnapshotScanPhase2(long untilAddress)
120
127
{
121
128
try
122
129
{
123
- Debug . Assert ( systemState . Phase == Phase . WAIT_FLUSH ) ;
124
-
125
130
// Iterate all the (v) records in the store
126
131
var scanFunctions = new ScanPhase2Functions ( streamingSnapshotIteratorFunctions , this . numberOfRecords ) ;
127
132
using var s = NewSession < Empty , Empty , Empty , StreamingSnapshotSessionFunctions > ( new ( ) ) ;
128
133
129
- // TODO: This requires ScanCursor to provide a consistent snapshot considering only records up to untilAddress
130
- // There is a bug in the current implementation of ScanCursor, where it does not provide such a consistent snapshot
131
134
_ = s . ScanCursor ( ref scannedUntilAddressCursor , long . MaxValue , scanFunctions , endAddress : untilAddress , maxAddress : untilAddress ) ;
132
135
133
136
// Reset the cursor to 0
@@ -136,13 +139,21 @@ internal void StreamingSnapshotScanPhase2(long untilAddress)
136
139
137
140
// Reset the callback functions
138
141
streamingSnapshotIteratorFunctions = null ;
139
-
140
- // Release the semaphore to allow the checkpoint waiting task to proceed
141
- _hybridLogCheckpoint . flushedSemaphore . Release ( ) ;
142
+ }
143
+ catch ( Exception e )
144
+ {
145
+ logger ? . LogError ( e , "Exception in StreamingSnapshotScanPhase2" ) ;
146
+ throw ;
142
147
}
143
148
finally
144
149
{
145
- Debug . Assert ( systemState . Phase == Phase . WAIT_FLUSH ) ;
150
+ // Release the semaphore to allow the checkpoint waiting task to proceed
151
+ _hybridLogCheckpoint . flushedSemaphore . Release ( ) ;
152
+
153
+ // We started this task before entering WAIT_FLUSH, so we
154
+ // need to wait until the state machine is in WAIT_FLUSH
155
+ while ( systemState . Phase != Phase . WAIT_FLUSH )
156
+ Thread . Yield ( ) ;
146
157
GlobalStateMachineStep ( systemState ) ;
147
158
}
148
159
}
0 commit comments