예제 #1
0
        private async Task <CdcState> SetInitialStateAsync(CancellationToken token, string executionId, TableSchema tableSchema, TimeSpan maxInterval)
        {
            byte[] initialToLsn = await _cdcReaderClient.GetMaxLsnAsync();

            var existingOffset = await _cdcReaderClient.GetLastCdcOffsetAsync(executionId, tableSchema.TableName);

            if (existingOffset.Result == Result.NoStoredState)
            {
                Console.WriteLine($"Table {tableSchema.TableName} - No previous stored offset. Starting from first change");
                var initialFromLsn = await _cdcReaderClient.GetMinValidLsnAsync(tableSchema.TableName);

                var          hasFirstChange = false;
                ChangeBatch  syncBatch      = null;
                ChangeRecord firstChange    = null;
                while (!hasFirstChange && !token.IsCancellationRequested)
                {
                    syncBatch = await _cdcReaderClient.GetChangeBatchAsync(tableSchema, initialFromLsn, initialToLsn, 1);

                    if (syncBatch.Changes.Any())
                    {
                        firstChange    = syncBatch.Changes.First();
                        hasFirstChange = true;
                    }
                    else
                    {
                        await Task.Delay(maxInterval);
                    }
                }

                await BlockingWriteToRedshiftAsync(token, tableSchema.TableName, syncBatch);

                var cdcState = new CdcState()
                {
                    FromLsn       = firstChange.Lsn,
                    FromSeqVal    = firstChange.SeqVal,
                    ToLsn         = initialToLsn,
                    UnfinishedLsn = syncBatch.MoreOfLastTransaction
                };

                var offset = GetOffset(cdcState);
                await _cdcReaderClient.StoreCdcOffsetAsync(executionId, tableSchema.TableName, offset);

                return(cdcState);
            }
            else
            {
                Console.WriteLine($"Table {tableSchema.TableName} - Starting from stored offset");

                return(new CdcState()
                {
                    FromLsn = existingOffset.State.Lsn,
                    FromSeqVal = existingOffset.State.SeqVal,
                    ToLsn = initialToLsn,
                    UnfinishedLsn = existingOffset.State.UnfinishedLsn
                });
            }
        }
예제 #2
0
        private Offset GetOffset(CdcState cdcState)
        {
            var offset = new Offset();

            offset.Lsn           = cdcState.FromLsn;
            offset.SeqVal        = cdcState.FromSeqVal;
            offset.UnfinishedLsn = cdcState.UnfinishedLsn;

            return(offset);
        }