Пример #1
0
        private IStoreV1CommunicationData TranslateMessage(ICommunicationMessage message)
        {
            if (!m_Converters.ContainsKey(message.GetType()))
            {
                throw new UnknownMessageTypeException();
            }

            var converter = m_Converters[message.GetType()];

            return(converter.FromMessage(message));
        }
Пример #2
0
        /// <summary>
        /// Sends the given message to the specified endpoint and returns a task that
        /// will eventually contain the return message.
        /// </summary>
        /// <param name="connection">The connection information for the endpoint to which the message has to be send.</param>
        /// <param name="message">The message that has to be send.</param>
        /// <param name="maximumNumberOfRetries">
        /// The maximum number of times the endpoint will try to send the message if delivery fails.
        /// </param>
        /// <param name="timeout">The maximum amount of time the response operation is allowed to take.</param>
        /// <returns>A task object that will eventually contain the response message.</returns>
        public Task <ICommunicationMessage> SendMessageToUnregisteredEndpointAndWaitForResponse(
            EndpointInformation connection,
            ICommunicationMessage message,
            int maximumNumberOfRetries,
            TimeSpan timeout)
        {
            {
                Lokad.Enforce.Argument(() => connection);
                Lokad.Enforce.Argument(() => message);
            }

            using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "ProtocolLayer: sending message and waiting for response"))
            {
                var pair   = ChannelPairFor(connection);
                var result = pair.Item2.ForwardResponse(connection.Id, message.Id, timeout);

                m_Diagnostics.Log(
                    LevelToLog.Trace,
                    CommunicationConstants.DefaultLogTextPrefix,
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "Sending msg of type {0} to endpoint ({1}) while waiting for the response.",
                        message.GetType(),
                        connection));

                pair.Item1.Send(connection.ProtocolInformation, message, maximumNumberOfRetries);

                RaiseOnConfirmChannelIntegrity(connection.Id);
                return(result);
            }
        }
Пример #3
0
        /// <summary>
        /// Sends the given message to the specified endpoint.
        /// </summary>
        /// <param name="connection">The connection information for the endpoint to which the message has to be send.</param>
        /// <param name="message">The message that has to be send.</param>
        /// <param name="maximumNumberOfRetries">The maximum number of times the endpoint will try to send the message if delivery fails.</param>
        /// <exception cref="FailedToSendMessageException">
        ///     Thrown when the channel fails to deliver the message to the remote endpoint.
        /// </exception>
        public void SendMessageToUnregisteredEndpoint(EndpointInformation connection, ICommunicationMessage message, int maximumNumberOfRetries)
        {
            {
                Lokad.Enforce.Argument(() => connection);
                Lokad.Enforce.Argument(() => message);
            }

            using (m_Diagnostics.Profiler.Measure(
                       CommunicationConstants.TimingGroup,
                       "ProtocolLayer: sending message without waiting for response"))
            {
                var channel = ChannelFor(connection);
                m_Diagnostics.Log(
                    LevelToLog.Trace,
                    CommunicationConstants.DefaultLogTextPrefix,
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "Sending msg of type {0} to endpoint ({1}) without waiting for the response.",
                        message.GetType(),
                        connection.Id));

                channel.Send(connection.ProtocolInformation, message, maximumNumberOfRetries);
                RaiseOnConfirmChannelIntegrity(connection.Id);
            }
        }
 public bool PassThrough(ICommunicationMessage message)
 {
     return((message != null) && m_MessageType.IsAssignableFrom(message.GetType()));
 }
 private static bool IsMessageIndicatingEndpointDisconnect(ICommunicationMessage message)
 {
     return(message.GetType().Equals(typeof(EndpointDisconnectMessage)));
 }
        /// <summary>
        /// Processes the message and invokes the desired functions based on the
        /// message contents or type.
        /// </summary>
        /// <param name="message">The message that should be processed.</param>
        public void ProcessMessage(ICommunicationMessage message)
        {
            {
                Lokad.Enforce.Argument(() => message);
            }

            using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "MessageHandler: processing message"))
            {
                // Confirm that the endpoint is still alive.
                RaiseOnConfirmChannelIntegrity(message.Sender);

                // First check that the message isn't a response. If it is then we see if we have a
                // waiting task for that. If not then the message will just disappear in the void
                if (!message.InResponseTo.Equals(MessageId.None))
                {
                    m_Diagnostics.Log(
                        LevelToLog.Trace,
                        CommunicationConstants.DefaultLogTextPrefix,
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Message [{0}] is a response to message [{1}].",
                            message.Id,
                            message.InResponseTo));

                    using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "Processing response message"))
                    {
                        Tuple <EndpointId, Subject <ICommunicationMessage>, CancellationTokenSource> source = null;
                        lock (m_Lock)
                        {
                            if (m_TasksWaitingForResponse.ContainsKey(message.InResponseTo))
                            {
                                source = m_TasksWaitingForResponse[message.InResponseTo];
                            }
                        }

                        // Invoke the OnNext and OnCompleted outside the lock because the setting of the
                        // result may lead to other messages being send and more responses
                        // being required to be handled. All of that may need access to the lock.
                        if (source != null)
                        {
                            source.Item2.OnNext(message);
                            source.Item2.OnCompleted();
                        }

                        return;
                    }
                }

                // Need to do message filtering here
                // Only accept messages from endpoints that we know of (and have accepted) or
                // messages that are handshakes / responses to handshakes
                if (!ShouldProcessMessage(message))
                {
                    return;
                }

                using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "Using message filters"))
                {
                    // The message isn't a response so go to the filters
                    // First copy the filters and their associated actions so that we can
                    // invoke the actions outside the lock. This is necessary because
                    // a message might invoke the requirement for more messages and eventual
                    // responses. Setting up a response requires that we can take out the lock
                    // again.
                    // Once we have the filters then we can just run past all of them and invoke
                    // the actions based on the filter pass through.
                    Dictionary <IMessageFilter, IMessageProcessAction> localCollection;
                    lock (m_Lock)
                    {
                        localCollection = new Dictionary <IMessageFilter, IMessageProcessAction>(m_Filters);
                    }

                    foreach (var pair in localCollection)
                    {
                        if (pair.Key.PassThrough(message))
                        {
                            m_Diagnostics.Log(
                                LevelToLog.Trace,
                                CommunicationConstants.DefaultLogTextPrefix,
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    "Processing message of type {0} with action of type {1}.",
                                    message.GetType(),
                                    pair.Value.GetType()));

                            pair.Value.Invoke(message);

                            // Each message type should only be procesed by one process action
                            // so if we find it, then we're done.
                            return;
                        }
                    }
                }

                // The message type is unknown. See if the last chance handler wants it ...
                if (m_LastChanceProcessor != null)
                {
                    m_LastChanceProcessor.Invoke(message);
                }
            }
        }