Exemple #1
0
        public bool IsClusterRequest <TResponse>(IClusterRequest <TResponse> request) where TResponse : BaseResponse
        {
            switch (request)
            {
            case ExecuteCommands t1:
                return(true);

            case RequestCreateIndex t1:
                return(true);

            case AddShardWriteOperation t1:
                return(true);

            case RequestDataShard t1:
                return(true);

            case AllocateShard t1:
                return(true);

            case ReplicateShardWriteOperation t1:
                return(true);

            case RequestShardWriteOperations t1:
                return(true);

            default:
                return(false);
            }
        }
Exemple #2
0
 public async Task <IActionResult> PostRPC([FromBody] IClusterRequest <BaseResponse> request)
 {
     if (request == null)
     {
         Logger.LogError("FOR SOME REASON THE REQUEST IS NULL");
     }
     return(Ok(await _handler.Handle(request)));
 }
Exemple #3
0
        public async Task <TResponse> Send <TResponse>(IClusterRequest <TResponse> request) where TResponse : BaseResponse
        {
            HttpResponseMessage result;

            switch (request)
            {
            case AddShardWriteOperation t1:
                result = await PostAsJsonAsync(_dataClient, "/api/node/RPC", request);

                break;

            case RequestShardWriteOperations t1:
                result = await PostAsJsonAsync(_dataClient, "/api/node/RPC", request);

                break;

            case RequestCreateIndex t1:
                result = await PostAsJsonAsync(_dataClient, "/api/node/RPC", request);

                break;

            case ReplicateShardWriteOperation t1:
                result = await PostAsJsonAsync(_dataClient, "/api/node/RPC", request);

                break;

            default:
                result = await PostAsJsonAsync(_httpClient, "/api/node/RPC", request);

                break;
            }

            try
            {
                if (result.IsSuccessStatusCode)
                {
                    return(JsonConvert.DeserializeObject <TResponse>(await result.Content.ReadAsStringAsync()));
                }
                else
                {
                    throw new Exception("Failed to send request with status code " + result.StatusCode + ".");
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
Exemple #4
0
 public async Task <TResponse> Send <TResponse>(Guid nodeId, IClusterRequest <TResponse> request) where TResponse : BaseResponse, new()
 {
     //if the request is for yourself
     if (_nodeStateService.Id == nodeId)
     {
         return(await Send(request));
     }
     if (_clusterConnectionPool.ContainsNode(nodeId))
     {
         return(await _clusterConnectionPool.GetNodeClient(nodeId).Send(request));
     }
     else
     {
         throw new MissingNodeConnectionDetailsException("Node " + nodeId + " was not found in available connections.");
     }
 }
Exemple #5
0
        public async Task <TResponse> HandleIfLeaderOrReroute <TResponse>(IClusterRequest <TResponse> request, Func <Task <TResponse> > Handle) where TResponse : BaseResponse, new()
        {
            var CurrentTime = DateTime.Now;

            // if you change and become a leader, just handle this yourself.
            if (_nodeStateService.Role != NodeState.Leader)
            {
                // Candidate, not in cluster or you still think current leader is yourself.
                if (_nodeStateService.Role == NodeState.Candidate || !_nodeStateService.InCluster || _nodeStateService.Id == _nodeStateService.CurrentLeader.Value)
                {
                    /* if ((DateTime.Now - CurrentTime).TotalMilliseconds < _clusterOptions.LatencyToleranceMs)
                     * {
                     *   _logger.LogWarning(_nodeStateService.GetNodeLogId() + "Currently a candidate during routing, will sleep thread and try again.");
                     *   Thread.Sleep(1000);
                     * }
                     * else
                     * {*/
                    return(new TResponse()
                    {
                        IsSuccessful = false
                    });
                    //}
                }
                else
                {
                    try
                    {
                        _logger.LogDebug(_nodeStateService.GetNodeLogId() + "Detected routing of command " + request.GetType().Name + " to leader.");
                        return((TResponse)(object)await _clusterClient.Send(_nodeStateService.CurrentLeader.Value, request));
                    }
                    catch (Exception e)
                    {
                        _logger.LogError(_nodeStateService.GetNodeLogId() + "Encountered " + e.Message + " while trying to route " + request.GetType().Name + " to leader.");
                        return(new TResponse()
                        {
                            IsSuccessful = false
                        });
                    }
                }
            }
            return(await Handle());
        }
Exemple #6
0
        public async Task <TResponse> Handle <TResponse>(IClusterRequest <TResponse> request) where TResponse : BaseResponse, new()
        {
            DateTime  commandStartTime = DateTime.Now;
            TResponse response;

            switch (request)
            {
            case ExecuteCommands t1:
                response = (TResponse)(object) await ExecuteCommandsRPCHandler(t1);

                break;

            case RequestVote t1:
                response = (TResponse)(object)RequestVoteRPCHandler(t1);
                break;

            case AppendEntry t1:
                response = (TResponse)(object)AppendEntryRPCHandler(t1);
                break;

            case InstallSnapshot t1:
                response = (TResponse)(object)InstallSnapshotHandler(t1);
                break;

            default:
                throw new Exception("Request is not implemented");
            }

            if (response != null)
            {
                return(response);
            }

            return(new TResponse()
            {
                IsSuccessful = false,
                ErrorMessage = "Response is null"
            });
        }
Exemple #7
0
        public async Task <TResponse> Handle <TResponse>(IClusterRequest <TResponse> request) where TResponse : BaseResponse, new()
        {
            try
            {
                DateTime  commandStartTime = DateTime.Now;
                TResponse response;
                switch (request)
                {
                case RequestDataShard t1:
                    response = (TResponse)(object) await RequestDataShardHandler(t1);

                    break;

                case AddShardWriteOperation t1:
                    response = (TResponse)(object) await AddShardWriteOperationHandler(t1);

                    break;

                case RequestCreateIndex t1:
                    response = (TResponse)(object) await RequestCreateIndexHandler(t1);

                    break;

                case AllocateShard t1:
                    response = (TResponse)(object) await AllocateShardHandler(t1);

                    break;

                case ReplicateShardWriteOperation t1:
                    response = (TResponse)(object) await ReplicateShardWriteOperationHandler(t1);

                    break;

                case RequestShardWriteOperations t1:
                    response = (TResponse)(object) await RequestShardWriteOperationsHandler(t1);

                    break;

                case RequestShardSync t1:
                    response = (TResponse)(object) await RequestShardSyncHandler(t1);

                    break;

                default:
                    throw new Exception("Request is not implemented");
                }

                return(response);
            }
            catch (TaskCanceledException e)
            {
                _logger.LogWarning(_nodeStateService.GetNodeLogId() + "Request " + request.RequestName + " timed out...");
                return(new TResponse()
                {
                    IsSuccessful = false
                });
            }
            catch (Exception e)
            {
                _logger.LogError(_nodeStateService.GetNodeLogId() + "Failed to handle request " + request.RequestName + " with error " + e.Message + Environment.StackTrace + e.StackTrace);
                return(new TResponse()
                {
                    IsSuccessful = false
                });
            }
        }
Exemple #8
0
        public async Task <TResponse> Handle <TResponse>(IClusterRequest <TResponse> request) where TResponse : BaseResponse, new()
        {
            _logger.LogDebug(_nodeStateService.GetNodeLogId() + "Detected RPC " + request.GetType().Name + "." + Environment.NewLine + JsonConvert.SerializeObject(request, Formatting.Indented));
            if (!_nodeStateService.IsBootstrapped)
            {
                _logger.LogDebug(_nodeStateService.GetNodeLogId() + "Node is not ready...");

                return(new TResponse()
                {
                    IsSuccessful = false,
                    ErrorMessage = "Node is not ready..."
                });
            }

            if (IsClusterRequest <TResponse>(request) && !_nodeStateService.InCluster)
            {
                _logger.LogWarning(_nodeStateService.GetNodeLogId() + "Reqeuest rejected, node is not apart of cluster...");
                return(new TResponse()
                {
                    IsSuccessful = false,
                    ErrorMessage = "Node is not apart of cluster..."
                });
            }

            DateTime commandStartTime = DateTime.Now;

            try
            {
                TResponse response;
                switch (request)
                {
                case ExecuteCommands t1:
                    response = await HandleIfLeaderOrReroute(request, async() => (TResponse)(object)await _raftService.Handle(t1));

                    break;

                case RequestVote t1:
                    response = (TResponse)(object)await _raftService.Handle(t1);

                    break;

                case AppendEntry t1:
                    response = (TResponse)(object)await _raftService.Handle(t1);

                    break;

                case InstallSnapshot t1:
                    response = (TResponse)(object)await _raftService.Handle(t1);

                    break;

                case RequestCreateIndex t1:
                    response = await HandleIfLeaderOrReroute(request, async() => (TResponse)(object)await _dataService.Handle(t1));

                    break;

                case AddShardWriteOperation t1:
                    response = (TResponse)(object)await _dataService.Handle(t1);

                    break;

                case RequestDataShard t1:
                    response = (TResponse)(object)await _dataService.Handle(t1);

                    break;

                case AllocateShard t1:
                    response = (TResponse)(object)await _dataService.Handle(t1);

                    break;

                case ReplicateShardWriteOperation t1:
                    response = (TResponse)(object)await _dataService.Handle(t1);

                    break;

                case RequestShardWriteOperations t1:
                    response = (TResponse)(object)await _dataService.Handle(t1);

                    break;

                default:
                    throw new Exception("Request is not implemented");
                }

                if (MetricGenerated != null && _nodeStateService.Role == NodeState.Leader && request.Metric)
                {
                    //Add and send
                    if (!lastMetricGenerated.ContainsKey(request.RequestName))
                    {
                        lastMetricGenerated.TryAdd(request.RequestName, DateTime.Now);
                        MetricGenerated.Invoke(this, new Metric()
                        {
                            Date       = DateTime.Now,
                            IntervalMs = 0,
                            Type       = MetricTypes.ClusterCommandElapsed(request.RequestName),
                            Value      = (DateTime.Now - commandStartTime).TotalMilliseconds
                        });
                    }
                    else if ((DateTime.Now - lastMetricGenerated[request.RequestName]).TotalMilliseconds > _clusterOptions.MetricsIntervalMs)
                    {
                        lastMetricGenerated.TryUpdate(request.RequestName, DateTime.Now, lastMetricGenerated[request.RequestName]);
                        MetricGenerated.Invoke(this, new Metric()
                        {
                            Date       = DateTime.Now,
                            IntervalMs = 0,
                            Type       = MetricTypes.ClusterCommandElapsed(request.RequestName),
                            Value      = (DateTime.Now - commandStartTime).TotalMilliseconds
                        });
                    }
                }

                return(response);
            }
            catch (TaskCanceledException e)
            {
                _logger.LogWarning(_nodeStateService.GetNodeLogId() + "Request " + request.RequestName + " timed out...");
                return(new TResponse()
                {
                    IsSuccessful = false
                });
            }
            catch (Exception e)
            {
                _logger.LogError(_nodeStateService.GetNodeLogId() + "Failed to handle request " + request.RequestName + " with error " + e.Message + Environment.StackTrace + e.StackTrace);
                return(new TResponse()
                {
                    IsSuccessful = false
                });
            }
        }
Exemple #9
0
 public async Task <TResponse> Send <TResponse>(IClusterRequest <TResponse> request) where TResponse : BaseResponse, new()
 {
     return(await _clusterRequestHandler.Handle(request));
 }