private TcpPackage WrapNotHandled(ClientMessage.NotHandled msg) { var dto = new TcpClientMessageDto.NotHandled(msg.Reason, msg.AdditionalInfo == null ? null : msg.AdditionalInfo.SerializeToArray()); return(new TcpPackage(TcpCommand.NotHandled, msg.CorrelationId, dto.Serialize())); }
private static ResponseConfiguration HandleNotHandled(Uri requestedUri, ClientMessage.NotHandled notHandled) { switch (notHandled.Reason) { case TcpClientMessageDto.NotHandled.NotHandledReason.NotReady: return(ServiceUnavailable("Server Is Not Ready")); case TcpClientMessageDto.NotHandled.NotHandledReason.TooBusy: return(ServiceUnavailable("Server Is Too Busy")); case TcpClientMessageDto.NotHandled.NotHandledReason.NotLeader: { var leaderInfo = notHandled.AdditionalInfo as TcpClientMessageDto.NotHandled.LeaderInfo; if (leaderInfo == null) { return(InternalServerError("No leader info available in response")); } return(TemporaryRedirect(requestedUri, leaderInfo.HttpAddress, leaderInfo.HttpPort)); } case TcpClientMessageDto.NotHandled.NotHandledReason.IsReadOnly: { var leaderInfo = notHandled.AdditionalInfo as TcpClientMessageDto.NotHandled.LeaderInfo; if (leaderInfo == null) { return(InternalServerError("No leader info available in response")); } return(DenyRequestBecauseReadOnly(requestedUri, leaderInfo.HttpAddress, leaderInfo.HttpPort)); } default: return(InternalServerError(string.Format("Unknown not handled reason: {0}", notHandled.Reason))); } }
public static bool TryHandleNotHandled(ClientMessage.NotHandled notHandled, out Exception exception) { exception = null; switch (notHandled.Reason) { case TcpClientMessageDto.NotHandled.NotHandledReason.NotReady: exception = ServerNotReady(); return(true); case TcpClientMessageDto.NotHandled.NotHandledReason.TooBusy: exception = ServerBusy(); return(true); case TcpClientMessageDto.NotHandled.NotHandledReason.NotMaster: case TcpClientMessageDto.NotHandled.NotHandledReason.IsReadOnly: switch (notHandled.AdditionalInfo) { case TcpClientMessageDto.NotHandled.MasterInfo _: return(false); default: exception = NoMasterInfo(); return(true); } default: return(false); } }
public static bool TryHandleNotHandled(ClientMessage.NotHandled notHandled, out Exception exception) { exception = null; switch (notHandled.Reason) { case TcpClientMessageDto.NotHandled.NotHandledReason.NotReady: exception = ServerNotReady(); return(true); case TcpClientMessageDto.NotHandled.NotHandledReason.TooBusy: exception = ServerBusy(); return(true); case TcpClientMessageDto.NotHandled.NotHandledReason.NotLeader: case TcpClientMessageDto.NotHandled.NotHandledReason.IsReadOnly: switch (notHandled.AdditionalInfo) { case TcpClientMessageDto.NotHandled.LeaderInfo leaderInfo: exception = LeaderInfo(new IPEndPoint(IPAddress.Parse(leaderInfo.ExternalHttpAddress), leaderInfo.ExternalHttpPort)); return(true); default: exception = NoLeaderInfo(); return(true); } default: return(false); } }
public static void HandleNotHandled <T>(ClientMessage.NotHandled notHandled, TaskCompletionSource <T> result) { switch (notHandled.Reason) { case TcpClientMessageDto.NotHandled.NotHandledReason.NotReady: result.TrySetException(ServerNotReady()); return; case TcpClientMessageDto.NotHandled.NotHandledReason.TooBusy: result.TrySetException(ServerBusy()); return; case TcpClientMessageDto.NotHandled.NotHandledReason.NotLeader: case TcpClientMessageDto.NotHandled.NotHandledReason.IsReadOnly: switch (notHandled.AdditionalInfo) { case TcpClientMessageDto.NotHandled.LeaderInfo _: return; default: result.TrySetException(NoLeaderInfo()); return; } default: return; } }
public NotHandled(ClientMessage.NotHandled source) { Reason = source.Reason switch { ClientMessage.NotHandled.Types.NotHandledReason.NotReady => Types.NotHandledReason.NotReady, ClientMessage.NotHandled.Types.NotHandledReason.TooBusy => Types.NotHandledReason.TooBusy, ClientMessage.NotHandled.Types.NotHandledReason.NotLeader => Types.NotHandledReason.NotLeader, ClientMessage.NotHandled.Types.NotHandledReason.IsReadOnly => Types.NotHandledReason.IsReadOnly, _ => throw new ArgumentOutOfRangeException() }; //this is horrible and only for transport compatibility purposes if (source.LeaderInfo != null) { AdditionalInfo = new Types.LeaderInfo(source.LeaderInfo.ExternalTcp, source.LeaderInfo.IsSecure, source.LeaderInfo.Http).ToByteString(); } } partial class Types {
private static ResponseConfiguration HandleNotHandled(Uri requestedUri, ClientMessage.NotHandled notHandled) { switch (notHandled.Reason) { case TcpClientMessageDto.NotHandled.NotHandledReason.NotReady: return ServiceUnavailable("Server Is Not Ready"); case TcpClientMessageDto.NotHandled.NotHandledReason.TooBusy: return ServiceUnavailable("Server Is Too Busy"); case TcpClientMessageDto.NotHandled.NotHandledReason.NotMaster: { var masterInfo = notHandled.AdditionalInfo as TcpClientMessageDto.NotHandled.MasterInfo; if (masterInfo == null) return InternalServerError("No master info available in response"); return TemporaryRedirect(requestedUri, masterInfo.ExternalHttpAddress, masterInfo.ExternalHttpPort); } default: return InternalServerError(string.Format("Unknown not handled reason: {0}", notHandled.Reason)); } }
private async Task Receive(ChannelWriter <BatchAppendResp> writer, ClaimsPrincipal user, bool requiresLeader, CancellationToken cancellationToken) { var pendingWrites = new ConcurrentDictionary <Guid, ClientWriteRequest>(); try { await foreach (var request in _requestStream.ReadAllAsync(cancellationToken)) { try { var correlationId = Uuid.FromDto(request.CorrelationId).ToGuid(); if (request.Options != null) { TimeSpan timeout = Min(GetRequestedTimeout(request.Options), _writeTimeout); if (!await _authorizationProvider.CheckAccessAsync(user, WriteOperation.WithParameter( Plugins.Authorization.Operations.Streams.Parameters.StreamId( request.Options.StreamIdentifier)), cancellationToken).ConfigureAwait(false)) { await writer.WriteAsync(new BatchAppendResp { CorrelationId = request.CorrelationId, StreamIdentifier = request.Options.StreamIdentifier, Error = Status.AccessDenied }, cancellationToken).ConfigureAwait(false); continue; } if (request.Options.StreamIdentifier == null) { await writer.WriteAsync(new BatchAppendResp { CorrelationId = request.CorrelationId, StreamIdentifier = request.Options.StreamIdentifier, Error = Status.BadRequest( $"Required field {nameof(request.Options.StreamIdentifier)} not set.") }, cancellationToken).ConfigureAwait(false); continue; } if (Max(timeout, TimeSpan.Zero) == TimeSpan.Zero) { await writer.WriteAsync(new BatchAppendResp { CorrelationId = request.CorrelationId, StreamIdentifier = request.Options.StreamIdentifier, Error = Status.Timeout }, cancellationToken).ConfigureAwait(false); continue; } pendingWrites.AddOrUpdate(correlationId, c => FromOptions(c, request.Options, timeout, cancellationToken), (_, writeRequest) => writeRequest); } if (!pendingWrites.TryGetValue(correlationId, out var clientWriteRequest)) { continue; } clientWriteRequest.AddEvents(request.ProposedMessages.Select(FromProposedMessage)); if (clientWriteRequest.Size > _maxAppendSize) { pendingWrites.TryRemove(correlationId, out _); await writer.WriteAsync(new BatchAppendResp { CorrelationId = request.CorrelationId, StreamIdentifier = clientWriteRequest.StreamId, Error = Status.MaximumAppendSizeExceeded((uint)_maxAppendSize) }, cancellationToken).ConfigureAwait(false); } if (!request.IsFinal) { continue; } if (!pendingWrites.TryRemove(correlationId, out _)) { continue; } Interlocked.Increment(ref _pending); _publisher.Publish(ToInternalMessage(clientWriteRequest, new CallbackEnvelope(message => { try { writer.TryWrite(ConvertMessage(message)); } catch (Exception ex) { writer.TryComplete(ex); } }), requiresLeader, user, cancellationToken)); BatchAppendResp ConvertMessage(Message message) { var batchAppendResp = message switch { ClientMessage.NotHandled notHandled => new BatchAppendResp { Error = new Status { Details = Any.Pack(new Empty()), Message = (notHandled.Reason, notHandled.AdditionalInfo) switch { (NotHandledReason.NotReady, _) => "Server Is Not Ready", (NotHandledReason.TooBusy, _) => "Server Is Busy", (NotHandledReason.NotLeader or NotHandledReason.IsReadOnly, LeaderInfo leaderInfo) => throw RpcExceptions.LeaderInfo(leaderInfo.HttpAddress, leaderInfo.HttpPort), (NotHandledReason.NotLeader or NotHandledReason.IsReadOnly, _) => "No leader info available in response", _ => $"Unknown {nameof(NotHandledReason)} ({(int)notHandled.Reason})" } } }, ClientMessage.WriteEventsCompleted completed => completed.Result switch { OperationResult.Success => new BatchAppendResp { Success = BatchAppendResp.Types.Success.Completed(completed.CommitPosition, completed.PreparePosition, completed.LastEventNumber), }, OperationResult.WrongExpectedVersion => new BatchAppendResp { Error = Status.WrongExpectedVersion( StreamRevision.FromInt64(completed.CurrentVersion), clientWriteRequest.ExpectedVersion) }, OperationResult.AccessDenied => new BatchAppendResp { Error = Status.AccessDenied }, OperationResult.StreamDeleted => new BatchAppendResp { Error = Status.StreamDeleted(clientWriteRequest.StreamId) }, OperationResult.CommitTimeout or OperationResult.ForwardTimeout or OperationResult.PrepareTimeout => new BatchAppendResp { Error = Status.Timeout }, _ => new BatchAppendResp { Error = Status.Unknown } }, _ => new BatchAppendResp { Error = new Status { Details = Any.Pack(new Empty()), Message = $"Envelope callback expected either {nameof(ClientMessage.WriteEventsCompleted)} or {nameof(ClientMessage.NotHandled)}, received {message.GetType().Name} instead" } } }; batchAppendResp.CorrelationId = Uuid.FromGuid(correlationId).ToDto(); batchAppendResp.StreamIdentifier = new StreamIdentifier { StreamName = ByteString.CopyFromUtf8(clientWriteRequest.StreamId) }; return(batchAppendResp); } } catch (Exception ex) { await writer.WriteAsync(new BatchAppendResp { CorrelationId = request.CorrelationId, StreamIdentifier = request.Options.StreamIdentifier, Error = Status.BadRequest(ex.Message) }, cancellationToken).ConfigureAwait(false); } }
public void Handle(ClientMessage.NotHandled message) { _forwardingProxy.TryForwardReply( message.CorrelationId, message, (clientCorrId, m) => new ClientMessage.NotHandled(clientCorrId, m.Reason, m.LeaderInfo)); }
public void Handle(ClientMessage.NotHandled message) { _requestTracker.RemovePendingRead(message.CorrelationId); }