예제 #1
0
        public bool Stop()
        {
            if (_membershipManager != null)
            {
                _membershipManager.StopHeartbeatTasks();
            }

            if (_connectionRestoration != null)
            {
                _connectionRestoration.Stop();
            }
            _connectionRestoration = null;

            IList <Server> keys = null;

            if (_shardChannels != null)
            {
                keys = _shardChannels.Keys.ToList();
            }
            if (keys != null && keys.Count > 0)
            {
                foreach (var server in keys)
                {
                    try
                    {
                        IDualChannel channel = _shardChannels[server];
                        lock (_shardChannels)
                        {
                            _shardChannels.Remove(server);
                            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                            {
                                LoggerManager.Instance.ShardLogger.Debug("Localshard.Stop(): ", server.Address.ToString() + " removed from existing channels.");
                            }
                        }
                        channel.ShouldTryReconnecting = false;
                        channel.Disconnect();
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Debug("Localshard.Stop(): ", "Connection of local node " + context.LocalAddress.ToString() + " disconected from node " + channel.PeerAddress.ToString());
                        }
                    }
                    catch (ChannelException ex)
                    {
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Error("Error stopping the node " + context.LocalAddress.ToString(), ex.ToString());
                        }
                    }
                }
            }
            lock (_mutexOnnodeRole)
            {
                if (NodeRole != NodeRole.Intermediate)
                {
                    NodeRole = Common.Configuration.Services.NodeRole.None;
                }
            }

            return(true);
        }
예제 #2
0
        //To-do: add ConnectStatus logic.
        public IDualChannel SetConnectInfo(IDualChannel channel, ConnectInfo.ConnectStatus status)
        {
            ConnectInfo connectInfo = null;

            if (((Address)_context.LocalAddress).CompareTo((Address)channel.PeerAddress) > 0)
            {
                connectInfo        = new ConnectInfo();
                connectInfo.Status = status;
                connectInfo.Id     = GetConnectionId();

                channel.SendMessage(connectInfo, true);
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Debug("ResolveChannelDispute.SetConnectInfo() ", "Node " + _context.LocalAddress.ToString() + ": Sender, " + "Node " + channel.PeerAddress.ToString() + ": Receiver.");
                }
            }
            // This specific check was necessary because somehow an earlier check for a condition was passing when it should not
            // look for an alternative way to this.
            else if (((Address)_context.LocalAddress).CompareTo((Address)channel.PeerAddress) < 0)
            {
                byte[] data = channel.ReadFromSocket();

                IRequest message = _shard.ChannelFormatter.Deserialize(data) as IRequest;
                connectInfo = message.Message as ConnectInfo;

                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Debug("ResolveChannelDispute.SetConnectInfo() ", "Node " + _context.LocalAddress.ToString() + ": Receiver, " + "Node " + channel.PeerAddress.ToString() + ": Sender.");
                }
            }
            channel.ConnectInfo = connectInfo;
            return(channel);
        }
예제 #3
0
        //Temporary overload added for the RemoteShard
        public IRequestResponseChannel GetValidChannel(IDualChannel newChannel, IRequestResponseChannel existingChannel)
        {
            IDictionary <Server, IDualChannel> existingChannelDic = new Dictionary <Server, IDualChannel>();

            if (existingChannel != null)
            {
                Server server = new Server(existingChannel.PeerAddress, Status.Initializing);
                existingChannelDic.Add(server, existingChannel as IDualChannel);
            }
            return(GetValidChannel(newChannel, existingChannelDic));
        }
예제 #4
0
        private void FormChannelConnection(Server server)
        {
            if (server.Address.Equals(context.LocalAddress))
            {
                try
                {
                    IDualChannel channel = new LocalChannel(context.LocalAddress, this);
                    lock (_shardChannels)
                    {
                        _shardChannels[server] = channel;
                    }
                }
                catch (Exception e)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Error("LocalShard.FormChannel()", "Local node: " + e.ToString());
                    }
                }
            }
            else
            {
                DualChannel channel = new DualChannel(server.Address.IpAddress.ToString(), server.Address.Port, context.LocalAddress.IpAddress.ToString(), SessionTypes.Shard, _traceProvider, _channelFormatter);
                try
                {
                    if (channel.Connect(false))
                    {
                        SessionInfo sessionInfo = new SessionInfo();
                        sessionInfo.Cluster = this.context.ClusterName;
                        sessionInfo.Shard   = this.context.LocalShardName;

                        channel.SendMessage(sessionInfo, true);

                        IDualChannel acceptedChannel = _resolveDispute.GetValidChannel(_resolveDispute.SetConnectInfo(channel, ConnectInfo.ConnectStatus.CONNECT_FIRST_TIME), _shardChannels);
                        lock (_shardChannels)
                        {
                            _shardChannels[server] = acceptedChannel;
                        }

                        _shardChannels[server].RegisterRequestHandler(this);
                        _shardChannels[server].StartReceiverThread();
                    }
                }
                catch (ChannelException ex)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Error("LocalShard.Start()", "Local shard: " + Name + ": Connection with " + server.Address + " failed to establish. " + ex);
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        ///     Bind Two Way (from and to the Source)
        /// </summary>
        /// <typeparam name = "T">Target <see cref = "ReactiveProperty{T}">ReactiveProperty</see> <see cref = "Type">Type</see></typeparam>
        /// <param name = "property">Target <see cref = "ReactiveProperty{T}">ReactiveProperty</see></param>
        /// <param name = "source">A <see cref = "TwoWayBinding{T}">TwoWayBinding</see> containing both an <see cref = "IObservable{T}">IObservable</see> and <see cref = "IObserver{T}">IObserver</see></param>
        public void Bind <T>(ReactiveProperty <T> property, IDualChannel <T> source)
        {
            var binding = source as TwoWayBinding <T>;

            if (binding != null)
            {
                this.SetBinding(property, binding.Initialize(this.GetSubject(property)));
            }
            else
            {
                this.Bind(property, source.Observable, source.Observer);
            }
        }
예제 #6
0
        public IAsyncResult BeginSendMessage(Server destination, object msg)
        {
            if (destination == null)
            {
                throw new ClusterException(ErrorCodes.Cluster.DESTINATION_NULL);
            }

            if (_shardChannels != null && _shardChannels.ContainsKey(destination))
            {
                IDualChannel channel = _shardChannels[destination];

                return(channel.BeginSendMessage(msg));
            }

            throw new ClusterException(ErrorCodes.Cluster.SERVER_NOT_EXIST);
        }
예제 #7
0
        public object SendUnicastMessage(Server destination, Object message)
        {
            if (destination == null)
            {
                throw new ClusterException(ErrorCodes.Cluster.DESTINATION_NULL);
            }

            if (this._shardChannels != null && _shardChannels.ContainsKey(destination))
            {
                IDualChannel channel = (IDualChannel)_shardChannels[destination];

                return(channel.SendMessage(message, false));
            }

            throw new ClusterException(ErrorCodes.Cluster.DESTINATION_SERVER_NOT_EXIST, new string[] { destination.Address.ToString() });
        }
예제 #8
0
        public IDualChannel GetValidChannel(IDualChannel channel, IDictionary <Server, IDualChannel> existingChannels)
        {
            Server server = new Server(channel.PeerAddress, Status.Running);

            if (!existingChannels.ContainsKey(server) || server.Address.Equals(_context.LocalAddress))
            {
                return(channel);
            }
            else
            {
                IDualChannel tempChannel = existingChannels[server];
                lock (existingChannels)
                {
                    existingChannels.Remove(server);
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Debug("ResolveChannelDispute.GetValidChannel(): ", server.Address.ToString() + " removed from existing channels.");
                    }
                }
                if (channel != null && channel.ConnectInfo != null && channel.ConnectInfo.Id < tempChannel.ConnectInfo.Id && channel.ConnectInfo.Status != ConnectInfo.ConnectStatus.CONNECT_FIRST_TIME)
                {
                    channel.ShouldTryReconnecting = false;
                    channel.Disconnect();
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Debug("ResolveChannelDispute.GetValidchannel(): if{}", "Connection of local node " + _context.LocalAddress.ToString() + " disconected from node " + channel.PeerAddress.ToString());
                    }
                    return(tempChannel);
                }
                else
                {
                    tempChannel.ShouldTryReconnecting = false;
                    try
                    {
                        tempChannel.Disconnect();
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Debug("ResolveChannelDispute.GetValidchannel(): else{}", "Connection of local node " + _context.LocalAddress.ToString() + " disconected from node " + tempChannel.PeerAddress.ToString());
                        }
                    }
                    catch (Exception e)
                    { }
                    //Thread.Sleep(1000);
                    return(channel);
                }
            }
        }
예제 #9
0
        public WsIQClientRx()
        {
            // TODO INJECT
            _ws            = new WebSocketWrapper();
            _epoch         = new Epoch();
            _randomNumbers = new RandomNumbers();

            MessagesFeed = Observable
                           .FromEventPattern <OnMessageEventHandler, WsRecievemessageEventArgs>(
                h => _ws.OnMessage += h,
                h => _ws.OnMessage -= h)
                           //.ObserveOn(NewThreadScheduler.Default)
                           .Map((e) =>
            {
                var serializedMessage = e.EventArgs.Message;
                var iQmessage         = JsonConvert.DeserializeObject <IQOptionMessage>(serializedMessage);
                return(iQmessage);
            });

            _onConnection = Observable
                            .FromEventPattern <OnConnectedEventHandler, EventArgs>(
                h => _ws.OnConnected += h,
                h => _ws.OnConnected -= h)
                            .Map(e => e.EventArgs)
                            .Replay();

            _onConnectionConnection = _onConnection.Connect();

            //TODO DO THIS IN THE IQCLient
            _ssidDualChannel = new SsidPublisherChannel(this);

            _heartBeatDualChannel = new HeartBeatDualChannel(this);

            _wsMessagesSubscription = _heartBeatDualChannel.ChannelFeed
                                      .Map(heartbeat => _heartBeatDualChannel.SendMessage(new HeartBeatOutputMessage(_epoch.EpochMilliSeconds, heartbeat.HeartbeatTime)))
                                      .Subscribe();

            _candleGeneratedDualChannel = new CandleGeneratedDualChannel(this);

            _serverTimeSync = new TimeSyncListenerChannel(this);

            _profileChannel = new ProfileListenerChannel(this);

            _listInfoDataChannelListener = new ListInfoDataListenerChannel(this);

            _buyV2ChannelPublisher = new BuyV2Channel(this, _epoch);
        }
예제 #10
0
        public object EndSendMessage(Server destination, IAsyncResult result)
        {
            Common.MiscUtil.IsArgumentNull(result);
            if (destination == null)
            {
                throw new ClusterException(ErrorCodes.Cluster.DESTINATION_NULL);
            }

            if (_shardChannels != null && _shardChannels.ContainsKey(destination))
            {
                IDualChannel channel = _shardChannels[destination];

                return(channel.EndSendMessage(result));
            }

            throw new ClusterException(ErrorCodes.Cluster.DESTINATION_SERVER_NOT_EXIST, new string[] { destination.Address.ToString() });
        }
예제 #11
0
        public void OnConnectionRestoration(IDualChannel channel)
        {
            Server      server      = new Server(channel.PeerAddress, Status.Running);
            SessionInfo sessionInfo = new SessionInfo();

            sessionInfo.Cluster = this.context.ClusterName;
            sessionInfo.Shard   = this.context.LocalShardName;

            channel.SendMessage(sessionInfo, true);

            IDualChannel acceptedChannel = _resolveDispute.GetValidChannel(_resolveDispute.SetConnectInfo(channel, ConnectInfo.ConnectStatus.RECONNECTING), _shardChannels);

            lock (_shardChannels)
            {
                _shardChannels[server] = acceptedChannel;
                _shardChannels[server].RegisterRequestHandler(this);
                _shardChannels[server].StartReceiverThread();
            }
        }
예제 #12
0
        public Boolean OnSessionEstablished(Session session)
        {
            Server       server      = new Server(new Common.Net.Address(session.IP.ToString(), session.LocalPort), Status.Initializing);
            IDualChannel channel     = new DualChannel(session.Connection, session.IP.ToString(), this.context.LocalAddress.Port, context.LocalAddress.ToString(), SessionTypes.Shard, _traceProvider, _channelFormatter);
            bool         isConnected = false;

            try
            {
                isConnected = channel.Connect(false);
            }
            catch (ChannelException e)
            {
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Error("Error: Localshard.OnSessionEstd()", e.ToString());
                }
            }
            if (isConnected)
            {
                ConnectInfo.ConnectStatus status = ConnectInfo.ConnectStatus.CONNECT_FIRST_TIME;
                if (_shardChannels.ContainsKey(server))
                {
                    status = ConnectInfo.ConnectStatus.RECONNECTING;
                }

                IDualChannel acceptedChannel = _resolveDispute.GetValidChannel(_resolveDispute.SetConnectInfo(channel, status), _shardChannels);

                lock (_shardChannels)
                {
                    _shardChannels[server] = acceptedChannel;
                }

                _shardChannels[server].RegisterRequestHandler(this);
                _shardChannels[server].StartReceiverThread();

                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #13
0
        public void OnConnectionRestoration(IDualChannel channel)
        {
            // check if the shardConnected event is required to be raised
            bool shardConnected = false;

            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
            {
                LoggerManager.Instance.ShardLogger.Debug("RemoteShard.OnConnectionRestoration()", "Before Connection Restoration for " + channel != null ? channel.PeerAddress.ToString() : "channel is null");
                LoggerManager.Instance.ShardLogger.Debug("RemoteShard.OnConnectionRestoration()", "Before Connection Restoration Should Retry " + channel != null ? channel.ShouldTryReconnecting.ToString() : "channel is null");
                LoggerManager.Instance.ShardLogger.Debug("RemoteShard.OnConnectionRestoration()", "Before Connection Restoration primary is  " + _remoteShardChannel != null ? _remoteShardChannel.PeerAddress.ToString() : "priamry is null");
            }

            SessionInfo info = new SessionInfo();

            info.Cluster = this.Context.ClusterName;
            info.Shard   = this.Context.LocalShardName;
            ((IRequestResponseChannel)channel).SendMessage(info, true);

            lock (_onChannel)
            {
                _remoteShardChannel = _resolveDispute.GetValidChannel(_resolveDispute.SetConnectInfo(channel, ConnectInfo.ConnectStatus.RECONNECTING), _remoteShardChannel);
                ((IDualChannel)_remoteShardChannel).StartReceiverThread();
                ((IDualChannel)_remoteShardChannel).RegisterRequestHandler(this);
                shardConnected = true;
            }
            lock (_onPrimary)
            {
                _primary = new Server(channel.PeerAddress, Status.Running);
            }

            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
            {
                LoggerManager.Instance.ShardLogger.Debug("RemoteShard.OnConnectionRestoration()", "After Connection Restoration for " + channel != null ? channel.PeerAddress.ToString() : "channel is null");
                LoggerManager.Instance.ShardLogger.Debug("RemoteShard.OnConnectionRestoration()", "After Connection Restoration Should Retry " + channel != null ? channel.ShouldTryReconnecting.ToString() : "channel is null");
            }

            if (shardConnected)
            {
                ShardConnected();
            }
        }
예제 #14
0
        public void ChannelDisconnected(IRequestResponseChannel channel, string reason)
        {
            try
            {
                if (_shardChannels != null)
                {
                    bool connected = false;

                    if (channel != null)
                    {
                        Server server = new Server(channel.PeerAddress, Status.Stopped);
                        Server key    = null;
                        if (_shardChannels != null)
                        {
                            IList <Server> shardchannelKeys = _shardChannels.Keys.ToList();
                            if (server != null && server.Address != null && !server.Address.Equals(context.LocalAddress) && shardchannelKeys != null && shardchannelKeys.Count > 0)
                            {
                                foreach (Server node in shardchannelKeys)
                                {
                                    if (_shardChannels[node].PeerAddress != null && _shardChannels[node].PeerAddress.Equals(channel.PeerAddress))
                                    {
                                        key = node;
                                        break;
                                    }
                                }
                            }
                            IDualChannel tempChannel = channel as IDualChannel;
                            if (tempChannel != null && key != null && tempChannel.ShouldTryReconnecting)
                            {
                                lock (_shardChannels)
                                {
                                    //_shardChannels[key].Disconnect();
                                    _shardChannels.Remove(key);
                                    if (LoggerManager.Instance.ShardLogger != null &&
                                        LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                                    {
                                        LoggerManager.Instance.ShardLogger.Debug("Localshard.Channeldisconnected(): ",
                                                                                 server.Address.ToString() + " removed from existing channels.");
                                    }
                                }
                                if (!key.Address.Equals(context.LocalAddress))
                                {
                                    BrokenConnectionInfo info = new BrokenConnectionInfo();
                                    info.BrokenAddress = key.Address;
                                    info.SessionType   = SessionTypes.Shard;

                                    _connectionRestoration.RegisterListener(info, this, context.LocalShardName);
                                }
                            }
                        }


                        try
                        {
                            if (!connected)
                            {
                                IShardListener listener = _shardListeners[Common.MiscUtil.CONFIGURATION_MANAGER];
                                listener.OnMemberLeft(new Server(channel.PeerAddress, Status.Stopped));
                            }
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }