private async Task <ShardWriteOperation> GetOrPopulateOperationCache(Guid shardId) { if (!_shardLastOperationCache.ContainsKey(shardId)) { var totalOperations = _shardRepository.GetTotalShardWriteOperationsCount(shardId); if (totalOperations != 0) { var lastOperation = await _shardRepository.GetShardWriteOperationAsync(shardId, totalOperations); _shardLastOperationCache.TryAdd(shardId, lastOperation); } else { return(null); } } return(_shardLastOperationCache[shardId]); }
/// <summary> /// Apply all unapplied operations /// </summary> public async void ResyncShardWriteOperations() { _logger.LogDebug("Resyncing Operations"); foreach (var shard in await _shardRepository.GetAllShardMetadataAsync()) { _logger.LogInformation("Checking shard " + shard.ShardId); var unappliedShardOperations = await _shardRepository.GetAllUnappliedOperationsAsync(shard.ShardId); foreach (var unappliedShardOperation in unappliedShardOperations) { ShardWriteOperation lastOperation; //If the previous operation exists and has been applied if ((lastOperation = await _shardRepository.GetShardWriteOperationAsync(unappliedShardOperation.Value.Data.ShardId.Value, unappliedShardOperation.Value.Pos - 1)) != null && lastOperation.Applied) { string newHash; //Run shard operation _writer.ApplyOperationToDatastore(unappliedShardOperation.Value); await _shardRepository.MarkShardWriteOperationAppliedAsync(unappliedShardOperation.Value.Id); } //Reverse all the last operations else { var removeFrom = unappliedShardOperation.Value.Pos; for (var i = _shardRepository.GetTotalShardWriteOperationsCount(shard.ShardId); i >= removeFrom; i--) { _logger.LogWarning("Detected out of order operations from " + removeFrom + ", removing operations onwards."); _writer.ReverseLocalTransaction(unappliedShardOperation.Value.Data.ShardId.Value, unappliedShardOperation.Value.Data.ShardType, i); } //Break out of loop break; } } } _logger.LogDebug("Finished Resyncing Operations"); }