示例#1
0
        public Bcl.IEnumerable <PeerConnection> FindRoutes(ExternalRouteLookupRequest lookupRequest)
        {
            var peers = new Bcl.List <PeerConnection>();

            if (lookupRequest.ReceiverNodeIdentity.IsSet())
            {
                if (nodeToConnectionMap.TryGetValue(lookupRequest.ReceiverNodeIdentity, out var peerConnection))
                {
                    peers.Add(peerConnection);
                }
            }
            else
            {
                if (messageToNodeMap.TryGetValue(lookupRequest.Message, out var nodes))
                {
                    if (lookupRequest.Distribution == DistributionPattern.Unicast)
                    {
                        peers.Add(nodeToConnectionMap[nodes.RoundRobinGet()]);
                    }
                    else
                    {
                        if (lookupRequest.Distribution == DistributionPattern.Broadcast)
                        {
                            foreach (var node in nodes)
                            {
                                peers.Add(nodeToConnectionMap[node]);
                            }
                        }
                    }
                }
            }

            return(peers);
        }
示例#2
0
        private bool SendToExactReceiver(Message message, ISocket scaleOutBackend, ExternalRouteLookupRequest lookupRequest)
        {
            if (Unsafe.ArraysEqual(message.ReceiverNodeIdentity, thisNodeIdentity))
            {
                var localDestinations = internalRoutingTable.FindRoutes(lookupRequest);
                return(SendMessageLocally(localDestinations, message));
            }

            var remoteDestinations = externalRoutingTable.FindRoutes(lookupRequest);

            return(SendMessageAway(remoteDestinations, message, scaleOutBackend));
        }
示例#3
0
        private bool HandleOperationMessage(Message message, ISocket scaleOutBackend)
        {
            var lookupRequest = new ExternalRouteLookupRequest
            {
                ReceiverIdentity     = new ReceiverIdentifier(message.ReceiverIdentity),
                Message              = new MessageIdentifier(message),
                Distribution         = message.Distribution,
                ReceiverNodeIdentity = new ReceiverIdentifier(message.ReceiverNodeIdentity ?? IdentityExtensions.Empty)
            };

            var handled = message.ReceiverNodeIdentity.IsSet()
                              ? SendToExactReceiver(message, scaleOutBackend, lookupRequest)
                              : SelectReceiverAndSend(message, scaleOutBackend, lookupRequest);

            return(handled || ProcessUnhandledMessage(message, lookupRequest));
        }
示例#4
0
        private bool ForwardMessageAway(ExternalRouteLookupRequest lookupRequest, Message message, ISocket scaleOutBackend)
        {
            var routes = message.Distribution == DistributionPattern.Broadcast && !MessageCameFromLocalActor(message)
                             ? Enumerable.Empty <PeerConnection>()
                             : externalRoutingTable.FindRoutes(lookupRequest);

            foreach (var route in routes)
            {
                try
                {
                    if (!route.Connected)
                    {
                        scaleOutBackend.Connect(route.Node.Uri, waitUntilConnected: true);
                        route.Connected = true;
                        clusterServices.GetClusterHealthMonitor()
                        .StartPeerMonitoring(new Node(route.Node.Uri, route.Node.SocketIdentity), route.Health);
                    }

                    message.SetSocketIdentity(route.Node.SocketIdentity);
                    message.AddHop();
                    message.PushRouterAddress(scaleOutConfigurationProvider.GetScaleOutAddress());

                    message.SignMessage(securityProvider);

                    scaleOutBackend.SendMessage(message);

                    ForwardedToOtherNode(message);
                }
                catch (TimeoutException err)
                {
                    clusterServices.GetClusterHealthMonitor()
                    .ScheduleConnectivityCheck(new ReceiverIdentifier(route.Node.SocketIdentity));
                    logger.Error(err);
                }
                catch (HostUnreachableException err)
                {
                    var unregMessage = new UnregisterUnreachableNodeMessage {
                        ReceiverNodeIdentity = route.Node.SocketIdentity
                    };
                    TryHandleServiceMessage(Message.Create(unregMessage).As <Message>(), scaleOutBackend);
                    logger.Error(err);
                }
            }

            return(routes.Any());
        }
示例#5
0
        private bool HandleOperationMessage(Message message, ISocket scaleOutBackend)
        {
            var lookupRequest = new ExternalRouteLookupRequest
            {
                ReceiverIdentity     = new ReceiverIdentifier(message.ReceiverIdentity),
                Message              = new MessageIdentifier(message),
                Distribution         = message.Distribution,
                ReceiverNodeIdentity = new ReceiverIdentifier(message.ReceiverNodeIdentity ?? IdentityExtensions.Empty)
            };
            var handleMessageLocally = !message.ReceiverNodeIdentity.IsSet() ||
                                       Unsafe.ArraysEqual(message.ReceiverNodeIdentity, thisNodeIdentity);

            var handled = handleMessageLocally && HandleMessageLocally(lookupRequest, message);

            if (!handled || message.Distribution == DistributionPattern.Broadcast)
            {
                handled = ForwardMessageAway(lookupRequest, message, scaleOutBackend) || handled;
            }

            return(handled || ProcessUnhandledMessage(message, lookupRequest));
        }
示例#6
0
        private bool ProcessUnhandledMessage(IMessage message, ExternalRouteLookupRequest lookupRequest)
        {
            var messageRoute = new Cluster.MessageRoute
            {
                Receiver = lookupRequest.ReceiverIdentity,
                Message  = lookupRequest.Message
            };

            clusterServices.GetClusterMonitor().DiscoverMessageRoute(messageRoute);

            if (MessageCameFromOtherNode(message))
            {
                clusterServices.GetClusterMonitor().UnregisterSelf(messageRoute.ToEnumerable());
            }
            var route = message.As <Message>().GetMessageRouting().FirstOrDefault();

            logger.Warn($"Route not found for Message:{lookupRequest.Message} lookup by " +
                        $"[{nameof(lookupRequest.ReceiverNodeIdentity)}:{lookupRequest.ReceiverNodeIdentity}]-" +
                        $"[{nameof(lookupRequest.ReceiverIdentity)}:{lookupRequest.ReceiverIdentity}]-" +
                        $"[{lookupRequest.Distribution}] " +
                        $"Sent by:[{route?.Identity.GetAnyString()}@{route?.Uri}]");

            return(true);
        }
示例#7
0
        private bool SelectReceiverAndSend(Message message, ISocket scaleOutBackend, ExternalRouteLookupRequest lookupRequest)
        {
            var handled = false;

            if (message.Distribution == DistributionPattern.Broadcast)
            {
                handled = SendMessageLocally(internalRoutingTable.FindRoutes(lookupRequest), message);
                handled = MessageCameFromLocalActor(message) &&
                          SendMessageAway(externalRoutingTable.FindRoutes(lookupRequest), message, scaleOutBackend) ||
                          handled;
            }
            else
            {
                var localDestinations  = internalRoutingTable.FindRoutes(lookupRequest);
                var remoteDestinations = externalRoutingTable.FindRoutes(lookupRequest);
                var local  = localDestinations.FirstOrDefault()?.As <IDestination>();
                var remote = remoteDestinations.FirstOrDefault()?.Node.As <IDestination>();

                var destination = (local != null && remote != null)
                                      ? roundRobinDestinationList.SelectNextDestination(local, remote)
                                      : (local ?? remote);
                if (destination != null)
                {
                    if (MessageCameFromOtherNode(message) || destination.Equals(local))
                    {
                        handled = SendMessageLocally(localDestinations, message);
                    }
                    if (!handled)
                    {
                        handled = SendMessageAway(remoteDestinations, message, scaleOutBackend);
                    }
                }
            }

            return(handled);
        }