/// <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.
 }
Exemple #3
0
		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());
        }
Exemple #5
0
 /// <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;
		}
Exemple #7
0
        /// <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;
        }
Exemple #8
0
		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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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();
        }
Exemple #13
0
 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);
             }
         }
     }
 }
Exemple #14
0
		/// <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;
 }
Exemple #23
0
 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
             );
     }
 }
Exemple #24
0
		/// <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
				}
			);
		}
Exemple #25
0
 /// <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;
 }
Exemple #26
0
        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 );
		}
Exemple #30
0
        /// <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
        }
Exemple #31
0
        /// <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();
            }
        }
Exemple #32
0
 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;
 }