예제 #1
0
        /// <summary>
        /// Begins asynchronous processing of a single <see cref="T:MySpace.DataRelay.RelayMessage"/>.
        /// </summary>
        /// <param name="message">The <see cref="T:MySpace.DataRelay.RelayMessage"/>.</param>
        /// <param name="state">Callers can put any state they like here.</param>
        /// <param name="callback">The method to call upon completion.</param>
        /// <returns>
        /// Returns an <see cref="T:System.IAsyncResult"/>.
        /// </returns>
        public IAsyncResult BeginHandleMessage(RelayMessage message, object state, AsyncCallback callback)
        {
            if (!message.IsTwoWayMessage)
            {
                // cheat for now and just handle in messages synchronously
                // as long as the type doesn't use sync in messages then
                // we won't block on IO anyway.
                HandleMessage(message);
                return(SynchronousAsyncResult.CreateAndComplete(callback, state));
            }


            SimpleLinkedList <Node> nodes = PrepareMessage(message, false);

            Node node;

            if (nodes.Pop(out node))
            {
                var result = new AsynchronousResult <Node>((ar, n, m) =>
                {
                    n.EndHandleOutMessage(ar);
                    int allowedRetries = NodeManager.Instance.GetRetryCountForMessage(message);
                    while (message.ErrorType == RelayErrorType.NodeUnreachable && --allowedRetries >= 0)
                    {
                        if (PrepareMessage(message, true).Pop(out node))
                        {
                            node.HandleOutMessage(message);
                        }
                        else
                        {
                            message.SetError(RelayErrorType.NoNodesAvailable);
                        }
                    }
                }, node, message);
                var origCallback = callback;
                if (callback != null)
                {
                    callback = ar =>
                    {
                        result.InnerResult = ar;
                        origCallback(result);
                    };
                }
                result.InnerResult = node.BeginHandleOutMessage(message, callback, state);
                return(result);
            }
            else
            {
                message.SetError(RelayErrorType.NoNodesAvailable);
            }
            return(SynchronousAsyncResult.CreateAndComplete(callback, state));
        }
예제 #2
0
        /// <summary>
        /// Begins asynchronous processing of a single <see cref="T:MySpace.DataRelay.RelayMessage"/>.
        /// </summary>
        /// <param name="message">The <see cref="T:MySpace.DataRelay.RelayMessage"/>.</param>
        /// <param name="state">Callers can put any state they like here.</param>
        /// <param name="callback">The method to call upon completion.</param>
        /// <returns>
        /// Returns an <see cref="T:System.IAsyncResult"/>.
        /// </returns>
        public virtual IAsyncResult BeginHandleMessage(RelayMessage message, object state, AsyncCallback callback)
        {
            if (!message.IsTwoWayMessage)
            {
                // cheat for now and just handle in messages synchronously
                // as long as the type doesn't use sync in messages then
                // we won't block on IO anyway.
                HandleMessage(message);
                return(SynchronousAsyncResult.CreateAndComplete(callback, state));
            }

            LinkedListStack <Node> nodes = PrepareMessage(message);

            Node node;

            if (nodes.Pop(out node))
            {
                var result = new AsynchronousResult <Node>((ar, n, m) =>
                {
                    try
                    {
                        n.EndHandleOutMessage(ar);
                        RetryHandleMessageOnError(message, node);
                    }
                    catch (Exception ex)
                    {
                        log.Error(ex);
                    }
                }, node, message);

                var origCallback = callback;
                if (callback != null)
                {
                    callback = ar =>
                    {
                        result.InnerResult = ar;
                        origCallback(result);
                    };
                }
                result.InnerResult = node.BeginHandleOutMessage(message, callback, state);
                return(result);
            }

            message.SetError(RelayErrorType.NoNodesAvailable);

            return(SynchronousAsyncResult.CreateAndComplete(callback, state));
        }
예제 #3
0
 /// <summary>
 /// Begins asynchronous processing of a <see cref="T:System.Collections.Generic.List`1"/> of <see cref="T:MySpace.DataRelay.RelayMessage"/>s.
 /// </summary>
 /// <param name="messages">The list of <see cref="T:MySpace.DataRelay.RelayMessage"/>s.</param>
 /// <param name="state">Callers can put any state they like here.</param>
 /// <param name="callback">The method to call upon completion.</param>
 /// <returns>
 /// Returns an <see cref="T:System.IAsyncResult"/>.
 /// </returns>
 /// <remarks>
 ///	<para>This method simply redirects to the synchronous <see cref="HandleMessages"/> method for now.
 ///	In the future this may change if we have compelling use-cases for making bulk message handling asynchronous.</para>
 /// </remarks>
 IAsyncResult IAsyncDataHandler.BeginHandleMessages(IList <RelayMessage> messages, object state, AsyncCallback callback)
 {
     // cheat and handle lists synchronously for now
     HandleMessages(messages);
     return(SynchronousAsyncResult.CreateAndComplete(callback, state));
 }