/// <summary> /// Raises <see cref="E:RpcServer.ClientError"/> event on the hosting <see cref="RpcServer"/>. /// </summary> /// <param name="context">The <see cref="ServerRequestContext"/> which holds client information.</param> /// <param name="rpcError">The <see cref="RpcErrorMessage"/> representing the error.</param> internal void RaiseClientError(ServerRequestContext context, RpcErrorMessage rpcError) { Contract.Requires(context != null); Contract.Requires(!rpcError.IsSuccess); this.Server.RaiseClientError(context, rpcError); }
protected override void OnReceiveCore( ReceivingContext context, ResponseMessage response, RpcErrorMessage error ) { base.OnReceiveCore( context, response, error ); this._connectionPool.Return( context.SocketContext ); context.SessionContext.Dispose(); // FIXME: Return to buffer pool. }
public void TestUnpackError_RoundTripped() { var detail = Guid.NewGuid().ToString(); var message = new RpcErrorMessage( RpcError.CallError, detail ); var context = CreateContext( message ); var result = ErrorInterpreter.UnpackError( context ); Assert.That( message == result, result.ToString() ); }
public void TestUnpackError_RoundTripped() { var detail = Guid.NewGuid().ToString(); var message = new RpcErrorMessage(RpcError.CallError, detail); var context = CreateContext(message); var result = ErrorInterpreter.UnpackError(context); Assert.That(message == result, result.ToString()); }
/// <summary> /// Raises the <see cref="E:ClientError"/> event. /// </summary> /// <param name="context">The context information.</param> /// <param name="rpcError">The RPC error.</param> internal void RaiseClientError(ServerRequestContext context, RpcErrorMessage rpcError) { this.OnClientError( new RpcClientErrorEventArgs(rpcError) { RemoteEndPoint = context.RemoteEndPoint, SessionId = context.SessionId, MessageId = context.MessageId } ); }
/// <summary> /// Initializes a new instance of the <see cref="AsyncInvocationResult"/> class. /// </summary> /// <param name="asyncTask"> /// The <see cref="Task"/> which represents asynchronous operation invocation itself. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="asyncTask"/> is <c>null</c>. /// </exception> public AsyncInvocationResult( Task asyncTask ) { if ( asyncTask == null ) { throw new ArgumentNullException( "asyncTask" ); } Contract.EndContractBlock(); this._asyncTask = asyncTask; this._invocationError = RpcErrorMessage.Success; }
/// <summary> /// Initializes a new instance of the <see cref="AsyncInvocationResult"/> class. /// </summary> /// <param name="asyncTask"> /// The <see cref="Task"/> which represents asynchronous operation invocation itself. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="asyncTask"/> is <c>null</c>. /// </exception> public AsyncInvocationResult(Task asyncTask) { if (asyncTask == null) { throw new ArgumentNullException("asyncTask"); } Contract.EndContractBlock(); this._asyncTask = asyncTask; this._invocationError = RpcErrorMessage.Success; }
private static ClientResponseContext CreateContext( RpcErrorMessage message ) { var context = new ClientResponseContext(); using ( var buffer = new MemoryStream() ) using ( var packer = Packer.Create( buffer, false ) ) { packer.Pack( message.Error.Identifier ); context.ErrorBuffer = new ByteArraySegmentStream( new[] { new ArraySegment<byte>( buffer.ToArray() ) } ); buffer.SetLength( 0 ); packer.Pack( message.Detail ); context.ResultBuffer = new ByteArraySegmentStream( new[] { new ArraySegment<byte>( buffer.ToArray() ) } ); } return context; }
/// <summary> /// Raises internal shutdown completion routine. /// </summary> /// <param name="e">The <see cref="MsgPack.Rpc.Protocols.ShutdownCompletedEventArgs"/> instance containing the event data.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="e"/> is <c>null</c>. /// </exception> protected virtual void OnShutdownCompleted(ShutdownCompletedEventArgs e) { if (e == null) { throw new ArgumentNullException("e"); } Contract.EndContractBlock(); var socket = Interlocked.Exchange(ref this._boundSocket, null); MsgPackRpcClientProtocolsTrace.TraceEvent( MsgPackRpcClientProtocolsTrace.TransportShutdownCompleted, "Transport shutdown is completed. {{ \"Socket\" : 0x{0:X}, \"RemoteEndPoint\" : \"{1}\", \"LocalEndPoint\" : \"{2}\" }}", GetHandle(socket), GetRemoteEndPoint(socket, default(MessageContext)), GetLocalEndPoint(socket) ); if (socket != null) { socket.Close(); } // Notify shutdown to waiting clients. // Note that it is OK from concurrency point of view because additional modifications are guarded via shutdown flag. var errorMessage = new RpcErrorMessage(RpcError.TransportError, String.Format(CultureInfo.CurrentCulture, "Transport is shutdown. Shutdown source is: {0}", e.Source), null); foreach (var entry in this._pendingRequestTable) { entry.Value(null, errorMessage.ToException(), false); } foreach (var entry in this._pendingNotificationTable) { entry.Value(errorMessage.ToException(), false); } this._pendingRequestTable.Clear(); this._pendingNotificationTable.Clear(); var handler = Interlocked.CompareExchange(ref this._shutdownCompleted, null, null); if (handler != null) { handler(this, e); } }
private static ClientResponseContext CreateContext(RpcErrorMessage message) { var context = new ClientResponseContext(); using (var buffer = new MemoryStream()) using (var packer = Packer.Create(buffer, false)) { packer.Pack(message.Error.Identifier); context.ErrorBuffer = new ByteArraySegmentStream(new[] { new ArraySegment <byte>(buffer.ToArray()) }); buffer.SetLength(0); packer.Pack(message.Detail); context.ResultBuffer = new ByteArraySegmentStream(new[] { new ArraySegment <byte>(buffer.ToArray()) }); } return(context); }
void HandleOrphan(int?messageId, long sessionId, EndPoint remoteEndPoint, RpcErrorMessage rpcError, MessagePackObject?returnValue) { var socket = BoundSocket; MsgPackRpcClientProtocolsTrace.TraceEvent( MsgPackRpcClientProtocolsTrace.OrphanError, "There are no handlers to handle message which has MessageID:{0}, SessionID:{1}. This may indicate runtime problem or due to client recycling. {{ \"Socket\" : 0x{2:X}, \"RemoteEndPoint\" : \"{3}\", \"LocalEndPoint\" : \"{4}\", \"SessionID\" :{1}, \"MessageID\" : {0}, \"Error\" : {5}, \"ReturnValue\" : {6}, \"CallStack\" : \"{7}\" }}", messageId == null ? "(null)" : messageId.Value.ToString(CultureInfo.InvariantCulture), sessionId, GetHandle(socket), remoteEndPoint, GetLocalEndPoint(socket), rpcError, returnValue, new StackTrace(0, true) ); manager.HandleOrphan(messageId, rpcError, returnValue); }
void OnWaitTimeout(MessageContext context) { Contract.Assert(context != null); var asClientRequestContext = context as ClientRequestContext; var socket = BoundSocket; MsgPackRpcClientProtocolsTrace.TraceEvent( MsgPackRpcClientProtocolsTrace.WaitTimeout, "Wait timeout. {{ \"Socket\" : 0x{0:X}, \"RemoteEndPoint\" : \"{1}\", \"LocalEndPoint\" : \"{2}\", \"Operation\" : \"{3}\", \"MessageType\" : \"{4}\" \"MessageId\" : {5}, \"BytesTransferred\" : {6}, \"Timeout\" : \"{7}\" }}", GetHandle(socket), GetRemoteEndPoint(socket, context), GetLocalEndPoint(socket), asClientRequestContext != null ? "Send" : "Receive", asClientRequestContext == null ? MessageType.Response : asClientRequestContext.MessageType, context.MessageId, context.BytesTransferred, manager.Configuration.WaitTimeout ); var rpcError = new RpcErrorMessage( RpcError.TimeoutError, new MessagePackObject( new MessagePackObjectDictionary(3) { { RpcException.messageKeyUtf8, asClientRequestContext != null ? "Wait timeout on sending." : "Wait timeout on receiving." }, { RpcException.debugInformationKeyUtf8, string.Empty }, { RpcTimeoutException.ClientTimeoutKeyUtf8, Manager.Configuration.WaitTimeout.Value.Ticks } }, true ) ); RaiseError(context.MessageId, context.SessionId, GetRemoteEndPoint(socket, context), rpcError, false); ResetConnection(); }
void RaiseError(int?messageId, long sessionId, EndPoint remoteEndPoint, RpcErrorMessage rpcError, bool completedSynchronously) { if (messageId != null) { Action <ClientResponseContext, Exception, bool> handler = null; try { pendingRequestTable.TryRemove(messageId.Value, out handler); } finally { if (handler == null) { HandleOrphan(messageId, sessionId, remoteEndPoint, rpcError, null); } else { handler(null, rpcError.ToException(), completedSynchronously); } } } else { Action <Exception, bool> handler = null; try { pendingNotificationTable.TryRemove(sessionId, out handler); } finally { if (handler == null) { HandleOrphan(messageId, sessionId, remoteEndPoint, rpcError, null); } else { handler(rpcError.ToException(), completedSynchronously); } } } }
/// <summary> /// Initializes a new instance of the <see cref="AsyncInvocationResult"/> class as error result. /// </summary> /// <param name="invocationError"> /// The <see cref="RpcErrorMessage"/> which represents the error of invocation itself. /// </param> public AsyncInvocationResult( RpcErrorMessage invocationError ) { this._asyncTask = null; this._invocationError = invocationError; }
/// <summary> /// Initializes a new instance of the <see cref="RpcClientErrorEventArgs"/> class. /// </summary> /// <param name="rpcError">The <see cref="RpcErrorMessage"/> represents client error.</param> public RpcClientErrorEventArgs( RpcErrorMessage rpcError ) { this._rpcError = rpcError; }
internal void HandleOrphan( int? messageId, RpcErrorMessage rpcError, MessagePackObject? returnValue ) { this.OnUnknownResponseReceived( new UnknownResponseReceivedEventArgs( messageId, rpcError, returnValue ) ); }
internal UnknownResponseReceivedEventArgs( int? messageId, RpcErrorMessage error, MessagePackObject? returnValue ) { this._messageId = messageId; this._error = error; this._returnValue = returnValue; }
/// <summary> /// Initialize new instance which represents RPC level error. /// </summary> /// <param name="operation">Last operation.</param> /// <param name="messageId">ID of message.</param> /// <param name="rpcError">Error.</param> public RpcTransportErrorEventArgs( RpcTransportOperation operation, int messageId, RpcErrorMessage rpcError ) { this._operation = operation; this._messageId = messageId; this._rpcError = rpcError; }
/// <summary> /// Serializes the specified response data. /// </summary> /// <typeparam name="T">The type of return value.</typeparam> /// <param name="returnValue">The return value.</param> /// <param name="error">The error.</param> /// <param name="returnValueSerializer">The serializer for the return value.</param> internal void Serialize <T>(T returnValue, RpcErrorMessage error, MessagePackSerializer <T> returnValueSerializer) { ServerTransport.Serialize(this, returnValue, error, returnValueSerializer); }
internal UnknownResponseReceivedEventArgs(int?messageId, RpcErrorMessage error, MessagePackObject?returnValue) { this._messageId = messageId; this._error = error; this._returnValue = returnValue; }
/// <summary> /// Set <see cref="SerializationError"/>. /// </summary> /// <param name="error">Error to be set.</param> internal void SetSerializationError( RpcErrorMessage error ) { this._serializationError = error; }
/// <summary> /// Initializes a new instance of the <see cref="RpcClientErrorEventArgs"/> class. /// </summary> /// <param name="rpcError">The <see cref="RpcErrorMessage"/> represents client error.</param> public RpcClientErrorEventArgs(RpcErrorMessage rpcError) { this._rpcError = rpcError; }
internal static void TraceInvocationResult <T>(long sessionId, MessageType messageType, int messageId, string operationId, RpcErrorMessage error, T result) { if (error.IsSuccess) { if (MsgPackRpcServerDispatchTrace.ShouldTrace(MsgPackRpcServerDispatchTrace.OperationSucceeded)) { MsgPackRpcServerDispatchTrace.TraceEvent( MsgPackRpcServerDispatchTrace.OperationSucceeded, "Operation succeeded. {{ \"SessionId\" : {0}, \"MessageType\" : \"{1}\", \"MessageID\" : {2}, \"OperationID\" : \"{3}\", \"Result\" : \"{4}\" }}", sessionId, messageType, messageId, operationId, result ); } } else { MsgPackRpcServerDispatchTrace.TraceEvent( MsgPackRpcServerDispatchTrace.OperationFailed, "Operation failed. {{ \"SessionId\" : {0}, \"MessageType\" : \"{1}\", \"MessageID\" : {2}, \"OperationID\" : \"{3}\", \"RpcError\" : {4} }}", sessionId, messageType, messageId, operationId, error ); } }
/// <summary> /// Raises the <see cref="E:ClientError"/> event. /// </summary> /// <param name="context">The context information.</param> /// <param name="rpcError">The RPC error.</param> internal void RaiseClientError( ServerRequestContext context, RpcErrorMessage rpcError ) { this.OnClientError( new RpcClientErrorEventArgs( rpcError ) { RemoteEndPoint = context.RemoteEndPoint, SessionId = context.SessionId, MessageId = context.MessageId } ); }
/// <summary> /// Initializes a new instance of the <see cref="AsyncInvocationResult"/> class as error result. /// </summary> /// <param name="invocationError"> /// The <see cref="RpcErrorMessage"/> which represents the error of invocation itself. /// </param> public AsyncInvocationResult(RpcErrorMessage invocationError) { this._asyncTask = null; this._invocationError = invocationError; }
void HandleDeserializationError(ClientResponseContext context, int?messageId, RpcErrorMessage rpcError, string message, Func <byte[]> invalidRequestHeaderProvider) { MsgPackRpcClientProtocolsTrace.TraceRpcError( rpcError.Error, "Deserialization error. {0} {{ \"Message ID\" : {1}, \"Error\" : {2} }}", message, messageId == null ? "(null)" : messageId.ToString(), rpcError ); if (invalidRequestHeaderProvider != null && MsgPackRpcClientProtocolsTrace.ShouldTrace(MsgPackRpcClientProtocolsTrace.DumpInvalidResponseHeader)) { var array = invalidRequestHeaderProvider(); MsgPackRpcClientProtocolsTrace.TraceData(MsgPackRpcClientProtocolsTrace.DumpInvalidResponseHeader, BitConverter.ToString(array), array); } RaiseError(messageId, context.SessionId, GetRemoteEndPoint(BoundSocket, context), rpcError, context.CompletedSynchronously); context.nextProcess = DumpCorrupttedData; }
protected virtual void OnReceiveCore( ReceivingContext context, ResponseMessage response, RpcErrorMessage error ) { IResponseHandler handler; bool removed; try { } finally { removed = this._sessionTable.TryRemove( response.MessageId, out handler ); this._sessionTableLatch.Signal(); } if ( removed ) { if ( error.IsSuccess ) { handler.HandleResponse( response, false ); } else { handler.HandleError( error, false ); } } else { // TODO: trace unrecognized receive message. } }
internal void HandleOrphan(int?messageId, RpcErrorMessage rpcError, MessagePackObject?returnValue) { this.OnUnknownResponseReceived(new UnknownResponseReceivedEventArgs(messageId, rpcError, returnValue)); }
/// <summary> /// Raises <see cref="E:RpcServer.ClientError"/> event on the hosting <see cref="RpcServer"/>. /// </summary> /// <param name="context">The <see cref="ServerRequestContext"/> which holds client information.</param> /// <param name="rpcError">The <see cref="RpcErrorMessage"/> representing the error.</param> internal void RaiseClientError( ServerRequestContext context, RpcErrorMessage rpcError ) { Contract.Requires( context != null ); Contract.Requires( !rpcError.IsSuccess ); this.Server.RaiseClientError( context, rpcError ); }
/// <summary> /// Dispatches the specified request, and dispatches the response to the specified transport. /// </summary> /// <param name="serverTransport">The server transport the response to be dispatched.</param> /// <param name="requestContext">The request context.</param> internal void Dispatch(ServerTransport serverTransport, ServerRequestContext requestContext) { Contract.Requires(serverTransport != null); Contract.Requires(requestContext != null); ServerResponseContext responseContext = null; if (requestContext.MessageType == MessageType.Request) { responseContext = serverTransport.Manager.GetResponseContext(requestContext); } Task task; var operation = this.Dispatch(requestContext.MethodName); if (operation == null) { var error = new RpcErrorMessage(RpcError.NoMethodError, "Operation does not exist.", null); InvocationHelper.TraceInvocationResult <object>( requestContext.SessionId, requestContext.MessageType, requestContext.MessageId.GetValueOrDefault(), requestContext.MethodName, error, null ); if (responseContext != null) { task = Task.Factory.StartNew(() => responseContext.Serialize <object>(null, error, null)); } else { return; } } else { task = operation(requestContext, responseContext); } var sessionState = Tuple.Create(this._server, requestContext.SessionId, requestContext.MessageType == MessageType.Request ? requestContext.MessageId : default(int?), requestContext.MethodName); #if NET_4_5 task.ContinueWith((previous, state) => { var tuple = state as Tuple < ServerTransport, ServerResponseContext, Tuple <RpcServer, long, int?, string>; SendResponse(previous, tuple.Item1, tuple.Item2, tuple.Item3) }, Tuple.Create(serverTransport, responseContext, sessionState) ).ContinueWith((previous, state) => { HandleSendFailure(previous, state as Tuple <RpcServer, long, int?, string>); }, TaskContinuationOptions.OnlyOnFaulted, sessionState ); #else task.ContinueWith(previous => { SendResponse(previous, serverTransport, responseContext, sessionState); } ).ContinueWith(previous => { HandleSendFailure(previous, sessionState); }, TaskContinuationOptions.OnlyOnFaulted ); #endif }
/// <summary> /// Raise error handler for specified RPC level error. /// </summary> /// <param name="operation">Last operation.</param> /// <param name="messageId">ID of message.</param> /// <param name="rpcError">RPC error.</param> /// <exception cref="RpcException"> /// There are no event handlers registered. /// </exception> protected void HandleError( RpcTransportOperation operation, int messageId, RpcErrorMessage rpcError ) { if ( rpcError.IsSuccess ) { return; } if ( !this.OnTransportError( new RpcTransportErrorEventArgs( operation, messageId, rpcError ) ) ) { throw rpcError.ToException(); } }
public Target(Exception fatalError, RpcErrorMessage methodError) : base(RpcServerRuntime.Create(RpcServerConfiguration.Default, new SerializationContext()), new ServiceDescription("Dummy", () => new object ()), typeof(object).GetMethod("ToString")) { this._fatalError = fatalError; this._methodError = methodError; }