Ejemplo n.º 1
0
        private void RetryPendingSubscriptions(IPEndPoint ep, Type type = null)
        {
            _log.DebugFormat("Retrying to find publishers for pending subscriptions {0}", type == null ? string.Empty : string.Format("of type {0}", type.Name));
            try
            {
                var cache = type == null?SubscriptionCache.ToArray() : SubscriptionCache.Where(c => c.Value == type).ToArray();

                foreach (var sub in cache)
                {
                    if (type != null && sub.Value != type)
                    {
                        return;
                    }

                    Message subscription = new Message(sub.Key)
                    {
                        Type = MessageType.Subscribe,
                        Data = Serializer.Serialize(sub.Value)
                    };

                    _log.DebugFormat("Resending subscription request message {0}", subscription.Id);
                    SenderBase.SendAsync(subscription, ep);
                }
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Could not retry pending subscriptions: {0}\n{1}", ex.Message, ex.StackTrace);
                return;
            }
        }
Ejemplo n.º 2
0
        public void BroadcastMessage(Message msg)
        {
            var remoteHosts = _messageProcessor.RemoteHosts.ToArray();

            foreach (var remoteHost in remoteHosts)
            {
                SenderBase.SendAsync(msg, remoteHost.Value);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Unsubscribes a node from the subscription defined by the subscription reference.
        /// </summary>
        /// <param name="subscriptionReference">The subscription reference.</param>
        /// <param name="nodeId">The node id.</param>
        public void UnsubscribeFrom(int subscriptionReference, int nodeId)
        {
            Message m = new Message(subscriptionReference)
            {
                Type = MessageType.Unsubscribe
            };
            var ep = ((IPEndPoint)_messageProcessor.RemoteHosts[nodeId]);

            SenderBase.SendAsync(m, ep);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Processes the discovery.
        /// </summary>
        /// <param name="e">The <see cref="MessageEventArgs"/> instance containing the event data.</param>
        private void ProcessDiscover(MessageEventArgs e)
        {
            /*
             * Respond to a discovery message
             */
            int        port = BitConverter.ToInt32(e.Message.Data, 4);
            IPEndPoint ep   = (IPEndPoint)e.Address;

            ep.Port = port;
            if (!RemoteHosts.ContainsKey(e.Message.Sender))
            {
                _log.InfoFormat("Discovered host {0} on {1}", e.Message.Sender, ep);
                try
                {
                    if (!AddRemoteHost(e, ep))
                    {
                        return;
                    }
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Could not add sender {0} to remotehosts list due to {1}", e.Message.Sender,
                                     ex.GetType().Name);
                }
            }
            else
            {
                //TODO is there an exception here???

                if ((RemoteHosts[e.Message.Sender] as IPEndPoint).Address.ToString() == ep.Address.ToString())
                {
                    _log.WarnFormat("Duplicate discovery message from node {0}", e.Message.Sender);
                }
                else
                {
                    _log.WarnFormat("Duplicate discovery message from node {0} from different address. Stored {1} New {2}", e.Message.Sender, (RemoteHosts[e.Message.Sender] as IPEndPoint).Address.ToString(), ep.Address.ToString());
                }
                //return;
            }
            byte[] portBytes = BitConverter.GetBytes(EllaConfiguration.Instance.NetworkPort);

            Message m = new Message {
                Type = MessageType.DiscoverResponse, Data = portBytes
            };

            SenderBase.SendMessage(m, ep);

            /*
             * EnqueueMessage a message to the new host and inquire about possible new publishers
             */

            Thread.Sleep(2000);
            RetryPendingSubscriptions(ep);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Sends a shutdown message.
        /// </summary>
        public void SendShutdownMessage()
        {
            Message m = new Message {
                Type = MessageType.NodeShutdown
            };

            foreach (var host in _messageProcessor.RemoteHosts)
            {
                var ep = host.Value;
                SenderBase.SendAsync(m, ep);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Subscribes to a remote host.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="callback"></param>
        public void SubscribeTo(Type type, Action <RemoteSubscriptionHandle> callback)
        {
            Message m = new Message {
                Type = MessageType.Subscribe, Data = Serializer.Serialize(type)
            };

            lock (_messageProcessor.PendingSubscriptions)
            {
                _messageProcessor.PendingSubscriptions.Add(m.Id, callback);
            }
            lock (_messageProcessor.SubscriptionCache)
            {
                _messageProcessor.SubscriptionCache.Add(m.Id, type);
            }
            foreach (IPEndPoint ep in _messageProcessor.RemoteHosts.Values.ToArray())
            {
                SenderBase.CreateSender(ep).SendAsync(m);
            }
        }
Ejemplo n.º 7
0
        public bool SendMessage(ApplicationMessage message, RemoteSubscriptionHandle remoteSubscriptionHandle, bool isReply = false)
        {
            Message m = new Message {
                Data = Serializer.Serialize(message), Type = isReply ? MessageType.ApplicationMessageResponse : MessageType.ApplicationMessage
            };
            var key = remoteSubscriptionHandle.PublisherNodeID == EllaConfiguration.Instance.NodeId ? remoteSubscriptionHandle.SubscriberNodeID : remoteSubscriptionHandle.PublisherNodeID;

            if (!_messageProcessor.RemoteHosts.ContainsKey(key))
            {
                return(false);
            }
            IPEndPoint ep = (IPEndPoint)_messageProcessor.RemoteHosts[key];

            if (ep != null)
            {
                SenderBase.SendAsync(m, ep);
                return(true);
            }
            return(false);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Processes the subscription.
        /// </summary>
        /// <param name="e">The <see cref="MessageEventArgs"/> instance containing the event data.</param>
        private void ProcessSubscribe(MessageEventArgs e)
        {
            Type type = null;

            try
            {
                type = Serializer.Deserialize <Type>(e.Message.Data);
                _log.DebugFormat("Processing remote subscription request for {0}", type.Name);
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Could not process remote subscription request. {0}", ex.Message);
                return;
            }
            //get the subscriptions that this node is already subscribed for, to avoid double subscriptions
            var currentHandles = (from s1 in (EllaModel.Instance.FilterSubscriptions(s => s.Event.EventDetail.DataType == type).Select(s => s.Handle)).OfType <RemoteSubscriptionHandle>()
                                  where s1.SubscriberNodeID == e.Message.Sender
                                  select s1).ToList().GroupBy(s => s.SubscriptionReference);

            IEnumerable <RemoteSubscriptionHandle> handles = SubscriptionController.SubscribeRemoteSubscriber(type, e.Message.Sender,
                                                                                                              (IPEndPoint)
                                                                                                              RemoteHosts[e.Message.Sender],
                                                                                                              e.Message.Id);

            /*
             * Sending reply
             */
            IPEndPoint ep = (IPEndPoint)RemoteHosts[e.Message.Sender];

            if (ep == null)
            {
                _log.ErrorFormat("No suitable endpoint to reply to subscription found");
                return;
            }
            if (handles != null)
            {
                //EnqueueMessage reply
                byte[] handledata = Serializer.Serialize(handles);
                byte[] reply      = new byte[handledata.Length + 4];
                byte[] idbytes    = BitConverter.GetBytes(e.Message.Id);
                Array.Copy(idbytes, reply, idbytes.Length);
                Array.Copy(handledata, 0, reply, idbytes.Length, handledata.Length);
                Message m = new Message {
                    Type = MessageType.SubscribeResponse, Data = reply
                };
                _log.DebugFormat("Replying to subscription request at {0}", ep);

                SenderBase.SendAsync(m, ep);
            }

            /*
             * Notify about previous subscriptions on the same type by the same node
             */
            foreach (var currentHandle in currentHandles)
            {
                //EnqueueMessage reply
                byte[] handledata = Serializer.Serialize(currentHandle.ToList());
                byte[] reply      = new byte[handledata.Length + 4];
                byte[] idbytes    = BitConverter.GetBytes(currentHandle.Key);
                Array.Copy(idbytes, reply, idbytes.Length);
                Array.Copy(handledata, 0, reply, idbytes.Length, handledata.Length);
                Message m = new Message {
                    Type = MessageType.SubscribeResponse, Data = reply
                };

                _log.DebugFormat("Sending previous subscription information to {0}", ep);
                SenderBase.SendAsync(m, ep);
            }
            _log.Debug("Checking for relevant event correlations");
            Thread.Sleep(1000);
            if (handles != null)
            {
                /*
                 * Process event correlations based on the subscription handles from the subscribe process
                 */
                foreach (var handle in handles)
                {
                    /*
                     * 1. search for correlations of this handle
                     * 2. send a message for each correlation#
                     */
                    var correlations = EllaModel.Instance.GetEventCorrelations(handle.EventHandle).ToArray();
                    foreach (var correlation in correlations)
                    {
                        KeyValuePair <EventHandle, EventHandle> pair =
                            new KeyValuePair <EventHandle, EventHandle>(handle.EventHandle, correlation);
                        Message m = new Message()
                        {
                            Type = MessageType.EventCorrelation,
                            Data = Serializer.Serialize(pair)
                        };
                        SenderBase.SendAsync(m, ep);
                    }
                }
            }
        }