public async Task <IChunk> ReadSingleBackwardAsync(string partitionId, long fromUpperIndexInclusive, CancellationToken cancellationToken) { using (var connection = Connect()) { await connection.OpenAsync(cancellationToken).ConfigureAwait(false); using (var command = new SqlCommand(_options.GetLastChunkScript(), connection)) { command.Parameters.AddWithValue("@PartitionId", partitionId); command.Parameters.AddWithValue("@toUpperIndexInclusive", fromUpperIndexInclusive); using (var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) { if (!reader.HasRows) { return(null); } await reader.ReadAsync(cancellationToken).ConfigureAwait(false); var chunk = new MsSqlChunk { Position = reader.GetInt64(0), PartitionId = reader.GetString(1), Index = reader.GetInt64(2), Payload = _options.Serializer.Deserialize(reader.GetString(3)), OperationId = reader.GetString(4), Deleted = reader.GetBoolean(5) }; return(chunk); } } } }
private async Task PushToSubscriber(SqlCommand command, long start, ISubscription subscription, CancellationToken cancellationToken) { long position = 0; await subscription.OnStart(start).ConfigureAwait(false); using (var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) { while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { position = reader.GetInt64(0); var chunk = new MsSqlChunk { Position = position, PartitionId = reader.GetString(1), Index = reader.GetInt64(2), Payload = _options.Serializer.Deserialize(reader.GetString(3)), OperationId = reader.GetString(4), Deleted = reader.GetBoolean(5) }; if (!await subscription.OnNext(chunk).ConfigureAwait(false)) { await subscription.Stopped(chunk.Position).ConfigureAwait(false); return; } } } await subscription.Completed(position).ConfigureAwait(false); }
private async Task PushToSubscriber(SqlCommand command, long start, ISubscription subscription, bool broadcastPosition, CancellationToken cancellationToken) { long indexOrPosition = 0; await subscription.OnStartAsync(start).ConfigureAwait(false); try { using (var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) { while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { var chunk = new MsSqlChunk { Position = reader.GetInt64(0), PartitionId = reader.GetString(1), Index = reader.GetInt64(2), OperationId = reader.GetString(4), }; indexOrPosition = broadcastPosition ? chunk.Position : chunk.Index; // to handle exceptions with correct position chunk.Payload = _options.Serializer.Deserialize(reader.GetString(3)); if (!await subscription.OnNextAsync(chunk).ConfigureAwait(false)) { await subscription.StoppedAsync(chunk.Position).ConfigureAwait(false); return; } } } await subscription.CompletedAsync(indexOrPosition).ConfigureAwait(false); } catch (Exception e) { await subscription.OnErrorAsync(indexOrPosition, e).ConfigureAwait(false); } }
private async Task <MsSqlChunk> ReadSingleChunk(SqlCommand command, CancellationToken cancellationToken) { using (var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) { if (!reader.HasRows) { return(null); } await reader.ReadAsync(cancellationToken).ConfigureAwait(false); var chunk = new MsSqlChunk { Position = reader.GetInt64(0), PartitionId = reader.GetString(1), Index = reader.GetInt64(2), OperationId = reader.GetString(4), Payload = _options.Serializer.Deserialize(reader.GetString(3)), }; return(chunk); } }
public async Task <IChunk> AppendAsync( string partitionId, long index, object payload, string operationId, CancellationToken cancellationToken) { if (index == -1) { index = Interlocked.Increment(ref USE_SEQUENCE_INSTEAD); } var chunk = new MsSqlChunk() { PartitionId = partitionId, Index = index, Payload = payload, OperationId = operationId ?? Guid.NewGuid().ToString() }; string textPayload = _options.Serializer.Serialize(payload); try { using (var connection = Connect()) { await connection.OpenAsync(cancellationToken).ConfigureAwait(false); using (var command = new SqlCommand(_options.GetPersistScript(), connection)) { command.Parameters.AddWithValue("@PartitionId", partitionId); command.Parameters.AddWithValue("@Index", index); command.Parameters.AddWithValue("@OperationId", chunk.OperationId); command.Parameters.AddWithValue("@Payload", textPayload); chunk.Position = (long)await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); } } } catch (SqlException ex) { if (ex.Number == DUPLICATED_INDEX_EXCEPTION) { if (ex.Message.Contains("_IDX")) { throw new DuplicateStreamIndexException(partitionId, index); } if (ex.Message.Contains("_OPID")) { _logger.LogInformation($"Skipped duplicated chunk on '{partitionId}' by operation id '{operationId}'"); return(null); } } _logger.LogError(ex.Message); throw; } return(chunk); }