Exemplo n.º 1
0
        public async void ReverseLocalTransaction(Guid shardId, string type, int pos)
        {
            var operation = await _shardRepository.GetShardWriteOperationAsync(shardId, pos);

            if (operation != null)
            {
                await _shardRepository.AddDataReversionRecordAsync(new DataReversionRecord()
                {
                    OriginalOperation = operation,
                    NewData           = operation.Data,
                    OriginalData      = await _dataRouter.GetDataAsync(type, operation.Data.Id),
                    RevertedTime      = DateTime.Now
                });

                ShardData data = operation.Data;
                SortedDictionary <int, ShardWriteOperation> allOperations;
                ShardWriteOperation lastObjectOperation = null;
                if (operation.Operation == ShardOperationOptions.Update || operation.Operation == ShardOperationOptions.Delete)
                {
                    allOperations = await _shardRepository.GetAllObjectShardWriteOperationAsync(data.ShardId.Value, data.Id);

                    lastObjectOperation = allOperations.Where(ao => ao.Key < operation.Pos).Last().Value;
                }

                switch (operation.Operation)
                {
                case ShardOperationOptions.Create:
                    data = await _dataRouter.GetDataAsync(type, operation.Data.Id);

                    if (data != null)
                    {
                        _logger.LogInformation(_nodeStateService.GetNodeLogId() + "Reverting create with deletion of " + data);
                        await _dataRouter.DeleteDataAsync(data);
                    }
                    break;

                // Put the data back in the right position
                case ShardOperationOptions.Delete:
                    await _dataRouter.InsertDataAsync(lastObjectOperation.Data);

                    break;

                case ShardOperationOptions.Update:
                    await _dataRouter.UpdateDataAsync(lastObjectOperation.Data);

                    break;
                }

                await _shardRepository.RemoveShardWriteOperationAsync(shardId, operation.Pos);
            }
            //Update the cache
            _shardLastOperationCache.Remove(operation.Data.ShardId.Value, out _);
        }
Exemplo n.º 2
0
        public async Task <ShardData> GetData(Guid objectId, string type, int timeoutMs, Guid?shardId = null)
        {
            Guid?FoundShard  = null;
            Guid?FoundOnNode = null;
            var  currentTime = DateTime.Now;

            if (shardId == null)
            {
                var shards = _stateMachine.GetAllPrimaryShards(type);

                bool      foundResult          = false;
                ShardData finalObject          = null;
                var       totalRespondedShards = 0;

                var tasks = shards.Select(async shard =>
                {
                    if (shard.Value != _nodeStateService.Id)
                    {
                        try
                        {
                            var result = await _clusterClient.Send(shard.Value, new RequestDataShard()
                            {
                                ObjectId = objectId,
                                ShardId  = shard.Key, //Set the shard
                                Type     = type
                            });

                            if (result.IsSuccessful)
                            {
                                foundResult = true;
                                finalObject = result.Data;
                                FoundShard  = result.ShardId;
                                FoundOnNode = result.NodeId;
                            }

                            Interlocked.Increment(ref totalRespondedShards);
                        }
                        catch (Exception e)
                        {
                            _logger.LogError(_nodeStateService.GetNodeLogId() + "Error thrown while getting " + e.Message);
                        }
                    }
                    else
                    {
                        finalObject = await _dataRouter.GetDataAsync(type, objectId);
                        foundResult = finalObject != null ? true : false;
                        FoundShard  = shard.Key;
                        FoundShard  = shard.Value;
                        Interlocked.Increment(ref totalRespondedShards);
                    }
                });

                //Don't await, this will trigger the tasks
                Task.WhenAll(tasks);

                while (!foundResult && totalRespondedShards < shards.Count)
                {
                    if ((DateTime.Now - currentTime).TotalMilliseconds > timeoutMs)
                    {
                        throw new ClusterOperationTimeoutException("Get data request for object " + objectId + " from shard " + shardId + " timed out.");
                    }
                    await Task.Delay(10);
                }

                return(finalObject);
            }
            else
            {
                return(await _dataRouter.GetDataAsync(type, objectId));
            }
        }