private async Task StartPublishingChanges(CancellationToken token, string executionId, string tableName, TimeSpan maxInterval, int batchSize) { var tableSchema = await _cdcReaderClient.GetTableSchemaAsync(tableName); var cdcState = await SetInitialStateAsync(token, executionId, tableSchema, maxInterval); var sw = new Stopwatch(); while (!token.IsCancellationRequested) { cdcState.ToLsn = await _cdcReaderClient.GetMaxLsnAsync(); sw.Start(); Console.WriteLine($"Table {tableName} - Starting to export LSN range {GetBigInteger(cdcState.FromLsn)} to {GetBigInteger(cdcState.ToLsn)}"); int blockCounter = 0; bool more = true; while (!token.IsCancellationRequested && more) { if (GetBigInteger(cdcState.FromLsn) <= GetBigInteger(cdcState.ToLsn)) { blockCounter++; ChangeBatch batch = null; if (cdcState.UnfinishedLsn) { batch = await _cdcReaderClient.GetChangeBatchAsync(tableSchema, cdcState.FromLsn, cdcState.FromSeqVal, cdcState.ToLsn, batchSize); } else { batch = await _cdcReaderClient.GetChangeBatchAsync(tableSchema, cdcState.FromLsn, cdcState.ToLsn, batchSize); } if (batch.Changes.Any()) { Console.WriteLine($"Table {tableName} - Retrieved block #{blockCounter} with {batch.Changes.Count} changes"); await BlockingWriteToRedshiftAsync(token, tableSchema.TableName, batch); cdcState.FromLsn = batch.Changes.Last().Lsn; cdcState.FromSeqVal = batch.Changes.Last().SeqVal; more = batch.MoreChanges; cdcState.UnfinishedLsn = batch.MoreOfLastTransaction; if (cdcState.UnfinishedLsn) { cdcState.FromSeqVal = Increment(cdcState.FromSeqVal); } else { cdcState.FromLsn = Increment(cdcState.FromLsn); } var offset = GetOffset(cdcState); await BlockingStoreCdcOffsetAsync(token, executionId, tableName, offset); } else { more = false; cdcState.UnfinishedLsn = false; Console.WriteLine($"Table {tableName} - No changes"); } } else { more = false; cdcState.UnfinishedLsn = false; Console.WriteLine($"Table {tableName} - No changes"); } } var remainingMs = maxInterval.TotalMilliseconds - sw.Elapsed.TotalMilliseconds; if (remainingMs > 0) { await Task.Delay((int)remainingMs); } sw.Reset(); } }
private async Task StartPublishingChanges(CancellationToken token, string executionId, string tableName, TimeSpan maxInterval, int batchSize, bool sendWithKey, SerializationMode serializationMode) { var tableTopic = _tableTopicPrefix + tableName.ToLower(); var tableSchema = await _cdcReaderClient.GetTableSchemaAsync(tableName); using (var producer = ProducerFactory.GetProducer(tableTopic, tableSchema, serializationMode, sendWithKey, _kafkaBootstrapServers, _schemaRegistryUrl)) { var cdcState = await SetInitialStateAsync(token, producer, executionId, tableSchema, maxInterval); var sw = new Stopwatch(); while (!token.IsCancellationRequested) { cdcState.ToLsn = await _cdcReaderClient.GetMaxLsnAsync(); sw.Start(); Console.WriteLine($"Table {tableName} - Starting to export LSN range {GetBigInteger(cdcState.FromLsn)} to {GetBigInteger(cdcState.ToLsn)}"); bool more = true; int blockCounter = 0; while (!token.IsCancellationRequested && more) { if (GetBigInteger(cdcState.FromLsn) <= GetBigInteger(cdcState.ToLsn)) { blockCounter++; ChangeBatch batch = null; if (cdcState.UnfinishedLsn) { batch = await _cdcReaderClient.GetChangeBatchAsync(tableSchema, cdcState.FromLsn, cdcState.FromSeqVal, cdcState.ToLsn, batchSize); } else { batch = await _cdcReaderClient.GetChangeBatchAsync(tableSchema, cdcState.FromLsn, cdcState.ToLsn, batchSize); } if (batch.Changes.Any()) { Console.WriteLine($"Table {tableName} - Retrieved block #{blockCounter} with {batch.Changes.Count} changes"); foreach (var change in batch.Changes) { await producer.SendAsync(token, change); cdcState.FromLsn = change.Lsn; cdcState.FromSeqVal = change.SeqVal; } more = batch.MoreChanges; cdcState.UnfinishedLsn = batch.MoreOfLastTransaction; if (cdcState.UnfinishedLsn) { cdcState.FromSeqVal = Increment(cdcState.FromSeqVal); } else { cdcState.FromLsn = Increment(cdcState.FromLsn); } var offset = GetOffset(cdcState); await BlockingStoreCdcOffsetAsync(token, executionId, tableName, offset); } else { more = false; cdcState.UnfinishedLsn = false; Console.WriteLine($"Table {tableName} - No changes"); } } else { more = false; cdcState.UnfinishedLsn = false; Console.WriteLine($"Table {tableName} - No changes"); } } var remainingMs = maxInterval.TotalMilliseconds - sw.Elapsed.TotalMilliseconds; if (remainingMs > 0) { await Task.Delay((int)remainingMs); } sw.Reset(); } } }