/// <summary>
        /// 获取有效的服务器地址
        /// </summary>
        /// <returns>有效的服务器地</returns>
        public static string[] GetConnectedSocketHost()
        {
            SockIO sock          = null;
            string connectedHost = null;

            foreach (string server in servers)
            {
                if (string.IsNullOrEmpty(server))
                {
                    continue;
                }

                try
                {
                    sock = SockIOPool.GetInstance(sockIOPool.Name).GetConnection(server);
                    if (sock != null)
                    {
                        connectedHost = connectedHost + server;
                    }
                }
                finally
                {
                    if (sock != null)
                    {
                        sock.Close();
                    }
                }
            }

            return(connectedHost.Split(','));
        }
Exemplo n.º 2
0
    public void CheckIn(SockIO socket, bool addToAvail)
    {
        if (socket == null)
        {
            return;
        }

        string host = socket.Host;

        //if(Log.IsDebugEnabled)
        //{
        //    Log.Debug("Calling check-in on socket: " + socket.ToString() + " for host: " + host);
        //}

        // remove from the busy pool
        //if(Log.IsDebugEnabled)
        //{
        //    Log.Debug("Removing socket (" + socket.ToString() + ") from busy pool for host: " + host);
        //}
        RemoveSocketFromPool(_busyPool, host, socket);

        // add to avail pool
        if (addToAvail && socket.IsConnected)
        {
            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug("Returning socket (" + socket.ToString() + " to avail pool for host: " + host);
            //}
            AddSocketToPool(_availPool, host, socket);
        }
    }
        /// <summary>
        /// Pair appication to registered applications in scatter
        /// </summary>
        /// <param name="passthrough">pass through rekey process</param>
        /// <param name="timeout">set response timeout that overrides the default one</param>
        /// <returns></returns>
        public async Task Pair(bool passthrough = false, int?timeout = null)
        {
            var pairOpenTask = new TaskCompletionSource <object>();
            var openTask     = new OpenTask()
            {
                PromiseTask     = pairOpenTask,
                TaskRequestTime = DateTime.Now,
                TaskTimeoutMS   = timeout.HasValue ? timeout.Value : TimeoutMS
            };

            if (OpenTasks.ContainsKey(PairOpenId))
            {
                OpenTasks[PairOpenId] = openTask;
            }
            else
            {
                OpenTasks.Add(PairOpenId, openTask);
            }

            await SockIO.EmitAsync("pair", new RequestWrapper()
            {
                data = new PairRequest()
                {
                    appkey      = StorageProvider.GetAppkey(),
                    passthrough = passthrough,
                    origin      = AppName
                },
                plugin = AppName
            });

            await pairOpenTask.Task;
        }
        public async Task <bool> Link(Uri uri)
        {
            if (SockIO.GetState() == WebSocketState.Open)
            {
                return(true);
            }

            if (SockIO.GetState() != WebSocketState.Open && SockIO.GetState() != WebSocketState.Connecting)
            {
                await SockIO.ConnectAsync(uri);
            }

            if (SockIO.GetState() != WebSocketState.Open)
            {
                return(false);
            }

            SockIO.On("paired", HandlePairedResponse);
            SockIO.On("rekey", HandleRekeyResponse);
            SockIO.On("api", HandleApiResponse);
            SockIO.On("event", HandleEventResponse);

            StartTimeoutOpenTasksCheck();

            await Pair(true);

            return(true);
        }
Exemplo n.º 5
0
        /// <summary>
        /// 获取有效的服务器地址
        /// </summary>
        /// <returns>有效的服务器地</returns>
        public static string[] GetConnectedSocketHost()
        {
            SockIO sock          = null;
            string connectedHost = null;

            foreach (string hostName in serverList)
            {
                if (!Discuz.Common.Utils.StrIsNullOrEmpty(hostName))
                {
                    try
                    {
                        sock = SockIOPool.GetInstance(memCachedConfigInfo.PoolName).GetConnection(hostName);
                        if (sock != null)
                        {
                            connectedHost = Discuz.Common.Utils.MergeString(hostName, connectedHost);
                        }
                    }
                    finally
                    {
                        if (sock != null)
                        {
                            sock.Close();
                        }
                    }
                }
            }
            return(Discuz.Common.Utils.SplitString(connectedHost, ","));
        }
Exemplo n.º 6
0
        /// <summary>
        /// 获取有效的服务器地址
        /// </summary>
        /// <returns>有效的服务器地</returns>
        public static string[] GetConnectedSocketHost()
        {
            SockIO sock          = null;
            string connectedHost = null;

            foreach (string hostName in serverList)
            {
                if (!string.IsNullOrEmpty(hostName))
                {
                    try
                    {
                        sock = SockIOPool.GetInstance(memCachedConfigInfo.PoolName).GetConnection(hostName);
                        if (sock != null)
                        {
                            connectedHost = hostName + "," + connectedHost;
                        }
                    }
                    finally
                    {
                        if (sock != null)
                        {
                            sock.Close();
                        }
                    }
                }
            }
            return(connectedHost.Split(','));
        }
 private void HandleRekeyResponse(IEnumerable <object> args)
 {
     GenerateNewAppKey();
     SockIO.EmitAsync("rekeyed", new
     {
         plugin = AppName,
         data   = new
         {
             origin = AppName,
             appkey = StorageProvider.GetAppkey()
         }
     });
 }
Exemplo n.º 8
0
    protected static void RemoveSocketFromPool(Hashtable pool, string host, SockIO socket)
    {
        if (host != null && host.Length == 0 || pool == null)
        {
            return;
        }

        if (pool.ContainsKey(host))
        {
            Hashtable sockets = (Hashtable)pool[host];
            if (sockets != null)
            {
                sockets.Remove(socket);
            }
        }
    }
        public async Task Pair(bool passthrough = false)
        {
            PairOpenTask = new TaskCompletionSource <bool>();

            await SockIO.EmitAsync("pair", new RequestWrapper()
            {
                data = new PairRequest()
                {
                    appkey      = StorageProvider.GetAppkey(),
                    passthrough = passthrough,
                    origin      = AppName
                },
                plugin = AppName
            });

            await PairOpenTask.Task;
        }
Exemplo n.º 10
0
        protected IEnumerator TimeoutOpenTasksCheck()
        {
            while (SockIO.GetState() == WebSocketState.Open)
            {
                var           now          = DateTime.Now;
                int           count        = 0;
                List <string> toRemoveKeys = new List <string>();

                foreach (var key in OpenTasks.Keys.ToList())
                {
                    OpenTask openTask;
                    if (!OpenTasks.TryGetValue(key, out openTask))
                    {
                        continue;
                    }

                    if ((now - openTask.TaskRequestTime).TotalMilliseconds >= openTask.TaskTimeoutMS)
                    {
                        toRemoveKeys.Add(key);
                    }

                    //sleep checking each 10 requests
                    if ((count % ScatterConstants.OPEN_TASK_NR_CHECK) == 0)
                    {
                        count = 0;
                        yield return(WaitForOpenTasksCheck(ScatterConstants.OPEN_TASK_CHECK_INTERVAL_SECS));
                    }

                    count++;
                }

                foreach (var key in toRemoveKeys)
                {
                    OpenTask openTask;
                    if (!OpenTasks.TryGetValue(key, out openTask))
                    {
                        continue;
                    }

                    OpenTasks.Remove(key);

                    openTask.PromiseTask.SetResult(BuildApiError());
                }
                yield return(WaitForOpenTasksCheck(ScatterConstants.OPEN_TASK_CHECK_INTERVAL_SECS));
            }
        }
        /// <summary>
        /// Send api request to scatter
        /// </summary>
        /// <typeparam name="TRequest">Request type param</typeparam>
        /// <typeparam name="TReturn">Return type param</typeparam>
        /// <param name="request">Request object</param>
        /// <param name="timeout">set response timeout that overrides the default one</param>
        /// <returns></returns>
        public async Task <TReturn> SendApiRequest <TRequest, TReturn>(Request <TRequest> request, int?timeout = null)
        {
            if (request.type == "identityFromPermissions" && !Paired)
            {
                return(default(TReturn));
            }

            await Pair();

            if (!Paired)
            {
                throw new Exception("The user did not allow this app to connect to their Scatter");
            }

            var tcs = new TaskCompletionSource <object>();

            do
            {
                request.id = UtilsHelper.RandomNumber(24);
            }while (OpenTasks.ContainsKey(request.id));

            request.appkey = StorageProvider.GetAppkey();
            request.nonce  = StorageProvider.GetNonce() ?? "";

            var nextNonce = UtilsHelper.RandomNumberBytes();

            request.nextNonce = UtilsHelper.ByteArrayToHexString(Sha256Manager.GetHash(nextNonce));
            StorageProvider.SetNonce(UtilsHelper.ByteArrayToHexString(nextNonce));

            OpenTasks.Add(request.id, new OpenTask()
            {
                PromiseTask     = tcs,
                TaskRequestTime = DateTime.Now,
                TaskTimeoutMS   = timeout.HasValue ? timeout.Value : TimeoutMS
            });

            await SockIO.EmitAsync("api", new RequestWrapper()
            {
                data   = request,
                plugin = AppName
            });

            return(BuildApiResponse <TReturn>(await tcs.Task));
        }
Exemplo n.º 12
0
        /// <summary>
        /// 获取当前缓存键值所存储在的服务器
        /// </summary>
        /// <param name="key">当前缓存键</param>
        /// <returns>当前缓存键值所存储在的服务器</returns>
        public static string GetSocketHost(string key)
        {
            string hostName = "";
            SockIO sock     = null;

            try
            {
                sock = SockIOPool.GetInstance(memCachedConfigInfo.PoolName).GetSock(key);
                if (sock != null)
                {
                    hostName = sock.Host;
                }
            }
            finally
            {
                if (sock != null)
                {
                    sock.Close();
                }
            }
            return(hostName);
        }
Exemplo n.º 13
0
    /// <summary>
    /// Adds a socket to a given pool for the given host.
    ///
    /// Internal utility method.
    /// </summary>
    /// <param name="pool">pool to add to</param>
    /// <param name="host">host this socket is connected to</param>
    /// <param name="socket">socket to add</param>
    //[MethodImpl(MethodImplOptions.Synchronized)]
    protected static void AddSocketToPool(Hashtable pool, string host, SockIO socket)
    {
        if (pool == null)
        {
            return;
        }

        Hashtable sockets;

        if (host != null && host.Length != 0 && pool.ContainsKey(host))
        {
            sockets = (Hashtable)pool[host];
            if (sockets != null)
            {
                sockets[socket] = DateTime.Now; //MaxM 1.16.05: Use current DateTime to indicate socker creation time rather than milliseconds since 1970

                return;
            }
        }

        sockets         = new Hashtable();
        sockets[socket] = DateTime.Now; //MaxM 1.16.05: Use current DateTime to indicate socker creation time rather than milliseconds since 1970
        pool[host]      = sockets;
    }
Exemplo n.º 14
0
        /// <summary>
        /// Checks a SockIO object in with the pool.
        /// 
        /// This will remove SocketIO from busy pool, and optionally<br/>
        /// add to avail pool.
        /// </summary>
        /// 
        /// <param name="socket">socket to return</param>
        /// <param name="addToAvail">add to avail pool if true</param>
        public virtual void CheckIn(SockIO socket, bool addToAvail)
        {
            lock (this)
            {

                string host = socket.Host;
                if(log.IsDebugEnabled) log.Debug("calling check-in on socket: " + socket.GetHashCode() + " for host: " + host);

                // remove from the busy pool
                if(log.IsDebugEnabled) log.Debug("removing socket (" + socket.GetHashCode() + ") from busy pool for host: " + host);
                RemoveSocketFromPool(busyPool, host, socket);

                // add to avail pool
                if (addToAvail && socket.Connected)
                {
                    if(log.IsDebugEnabled) log.Debug("returning socket (" + socket.GetHashCode() + " to avail pool for host: " + host);
                    AddSocketToPool(availPool, host, socket);
                }
            }
        }
Exemplo n.º 15
0
 public void CheckIn(SockIO socket)
 {
     CheckIn(socket, true);
 }
Exemplo n.º 16
0
        /// <summary>
        /// Adds a socket to a given pool for the given host.
        /// 
        /// Internal utility method. 
        /// </summary>
        /// <param name="pool">pool to add to</param>
        /// <param name="host">host this socket is connected to</param>
        /// <param name="socket">socket to add</param>
        //[MethodImpl(MethodImplOptions.Synchronized)]
        protected static void AddSocketToPool(Hashtable pool, string host, SockIO socket)
        {
            if (pool == null)
                return;

            Hashtable sockets;
            if (host != null && host.Length != 0 && pool.ContainsKey(host))
            {
                sockets = (Hashtable)pool[host];
                if (sockets != null)
                {
                    sockets[socket] = DateTime.Now; //MaxM 1.16.05: Use current DateTime to indicate socker creation time rather than milliseconds since 1970

                    return;
                }
            }

            sockets = new Hashtable();
            sockets[socket] = DateTime.Now; //MaxM 1.16.05: Use current DateTime to indicate socker creation time rather than milliseconds since 1970
            pool[host] = sockets;
        }
Exemplo n.º 17
0
        protected static void RemoveSocketFromPool(Hashtable pool, string host, SockIO socket)
        {
            if (host != null && host.Length == 0 || pool == null)
                return;

            if (pool.ContainsKey(host))
            {
                Hashtable sockets = (Hashtable)pool[host];
                if (sockets != null)
                {
                    sockets.Remove(socket);
                }
            }
        }
Exemplo n.º 18
0
    public SockIO GetConnection(string host)
    {
        if (!_initialized)
        {
            //if(Log.IsErrorEnabled)
            //{
            //    Log.Error(GetLocalizedString("get socket from uninitialized pool"));
            //}
            return(null);
        }

        if (host == null)
        {
            return(null);
        }

        // if we have items in the pool
        // then we can return it
        if (_availPool != null && !(_availPool.Count == 0))
        {
            // take first connected socket
            Hashtable aSockets = (Hashtable)_availPool[host];

            if (aSockets != null && !(aSockets.Count == 0))
            {
                foreach (SockIO socket in new IteratorIsolateCollection(aSockets.Keys))
                {
                    if (socket.IsConnected)
                    {
                        //if(Log.IsDebugEnabled)
                        //{
                        //    Log.Debug(GetLocalizedString("move socket").Replace("$$Host$$", host).Replace("$$Socket$$", socket.ToString()));
                        //}

                        // remove from avail pool
                        aSockets.Remove(socket);

                        // add to busy pool
                        AddSocketToPool(_busyPool, host, socket);

                        // return socket
                        return(socket);
                    }
                    else
                    {
                        // not connected, so we need to remove it
                        //if(Log.IsErrorEnabled)
                        //{
                        //    Log.Error(GetLocalizedString("socket not connected").Replace("$$Host$$", host).Replace("$$Socket$$", socket.ToString()));
                        //}

                        // remove from avail pool
                        aSockets.Remove(socket);
                    }
                }
            }
        }

        // if here, then we found no sockets in the pool
        // try to create on a sliding scale up to maxCreate
        object cShift = _createShift[host];
        int    shift  = (cShift != null) ? (int)cShift : 0;

        int create = 1 << shift;

        if (create >= _maxCreate)
        {
            create = _maxCreate;
        }
        else
        {
            shift++;
        }

        // store the shift value for this host
        _createShift[host] = shift;

        //if(Log.IsDebugEnabled)
        //{
        //    Log.Debug(GetLocalizedString("creating sockets").Replace("$$Create$$", create.ToString(new NumberFormatInfo())));
        //}

        for (int i = create; i > 0; i--)
        {
            SockIO socket = CreateSocket(host);
            if (socket == null)
            {
                break;
            }

            if (i == 1)
            {
                // last iteration, add to busy pool and return sockio
                AddSocketToPool(_busyPool, host, socket);
                return(socket);
            }
            else
            {
                // add to avail pool
                AddSocketToPool(_availPool, host, socket);
            }
        }

        // should never get here
        return(null);
    }
Exemplo n.º 19
0
    /// <summary>
    /// Returns appropriate SockIO object given
    /// string cache key and optional hashcode.
    ///
    /// Trys to get SockIO from pool.  Fails over
    /// to additional pools in event of server failure.
    /// </summary>
    /// <param name="key">hashcode for cache key</param>
    /// <param name="hashCode">if not null, then the int hashcode to use</param>
    /// <returns>SockIO obj connected to server</returns>
    public SockIO GetSock(string key, object hashCode)
    {
        string hashCodeString = "<null>";

        if (hashCode != null)
        {
            hashCodeString = hashCode.ToString();
        }

        //if(Log.IsDebugEnabled)
        //{
        //    Log.Debug(GetLocalizedString("cache socket pick").Replace("$$Key$$", key).Replace("$$HashCode$$", hashCodeString));
        //}

        if (key == null || key.Length == 0)
        {
            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug(GetLocalizedString("null key"));
            //}
            return(null);
        }

        if (!_initialized)
        {
            //if(Log.IsErrorEnabled)
            //{
            //    Log.Error(GetLocalizedString("get socket from uninitialized pool"));
            //}
            return(null);
        }

        // if no servers return null
        if (_buckets.Count == 0)
        {
            return(null);
        }

        // if only one server, return it
        if (_buckets.Count == 1)
        {
            return(GetConnection((string)_buckets[0]));
        }

        int tries = 0;

        // generate hashcode
        int hv;

        if (hashCode != null)
        {
            hv = (int)hashCode;
        }
        else
        {
            // NATIVE_HASH = 0
            // OLD_COMPAT_HASH = 1
            // NEW_COMPAT_HASH = 2
            switch (_hashingAlgorithm)
            {
            case HashingAlgorithm.Native:
                hv = key.GetHashCode();
                break;

            case HashingAlgorithm.OldCompatibleHash:
                hv = OriginalHashingAlgorithm(key);
                break;

            case HashingAlgorithm.NewCompatibleHash:
                hv = NewHashingAlgorithm(key);
                break;

            default:
                // use the native hash as a default
                hv = key.GetHashCode();
                _hashingAlgorithm = HashingAlgorithm.Native;
                break;
            }
        }

        // keep trying different servers until we find one
        while (tries++ <= _buckets.Count)
        {
            // get bucket using hashcode
            // get one from factory
            int bucket = hv % _buckets.Count;
            if (bucket < 0)
            {
                bucket += _buckets.Count;
            }

            SockIO sock = GetConnection((string)_buckets[bucket]);

            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug(GetLocalizedString("cache choose").Replace("$$Bucket$$", _buckets[bucket].ToString()).Replace("$$Key$$", key));
            //}

            if (sock != null)
            {
                return(sock);
            }

            // if we do not want to failover, then bail here
            if (!_failover)
            {
                return(null);
            }

            // if we failed to get a socket from this server
            // then we try again by adding an incrementer to the
            // current key and then rehashing
            switch (_hashingAlgorithm)
            {
            case HashingAlgorithm.Native:
                hv += ((string)("" + tries + key)).GetHashCode();
                break;

            case HashingAlgorithm.OldCompatibleHash:
                hv += OriginalHashingAlgorithm("" + tries + key);
                break;

            case HashingAlgorithm.NewCompatibleHash:
                hv += NewHashingAlgorithm("" + tries + key);
                break;

            default:
                // use the native hash as a default
                hv += ((string)("" + tries + key)).GetHashCode();
                _hashingAlgorithm = HashingAlgorithm.Native;
                break;
            }
        }

        return(null);
    }
Exemplo n.º 20
0
    /// <summary>
    /// Creates a new SockIO obj for the given server.
    ///
    ///If server fails to connect, then return null and do not try
    ///again until a duration has passed.  This duration will grow
    ///by doubling after each failed attempt to connect.
    /// </summary>
    /// <param name="host">host:port to connect to</param>
    /// <returns>SockIO obj or null if failed to create</returns>
    protected SockIO CreateSocket(string host)
    {
        SockIO socket = null;

        // if host is dead, then we don't need to try again
        // until the dead status has expired
        // we do not try to put back in if failover is off
        if (_failover && _hostDead.ContainsKey(host) && _hostDeadDuration.ContainsKey(host))
        {
            DateTime store  = (DateTime)_hostDead[host];
            long     expire = ((long)_hostDeadDuration[host]);

            if ((store.AddMilliseconds(expire)) > DateTime.Now)
            {
                return(null);
            }
        }

        try
        {
            socket = new SockIO(this, host, _socketTimeout, _socketConnectTimeout, _nagle);

            if (!socket.IsConnected)
            {
                //if(Log.IsErrorEnabled)
                //{
                //    Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host));
                //}
                try
                {
                    socket.TrueClose();
                }
                catch//(SocketException ex)
                {
                    //if(Log.IsErrorEnabled)
                    //{
                    //    Log.Error(GetLocalizedString("failed to close socket on host").Replace("$$Host$$", host), ex);
                    //}
                    socket = null;
                }
            }
        }
        catch (SocketException ex)
        {
            //if(Log.IsErrorEnabled)
            //{
            //    Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host), ex);
            //}
            socket = null;
        }
        //catch(ArgumentException ex)
        //{
        //    if(Log.IsErrorEnabled)
        //    {
        //        Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host), ex);
        //    }
        //    socket = null;
        //}
        //catch(IOException ex)
        //{
        //    if(Log.IsErrorEnabled)
        //    {
        //        Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host), ex);
        //    }
        //    socket = null;
        //}

        // if we failed to get socket, then mark
        // host dead for a duration which falls off
        if (socket == null)
        {
            DateTime now = DateTime.Now;
            _hostDead[host] = now;
            long expire = (_hostDeadDuration.ContainsKey(host)) ? (((long)_hostDeadDuration[host]) * 2) : 100;
            _hostDeadDuration[host] = expire;
            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug(GetLocalizedString("ignoring dead host").Replace("$$Host$$", host).Replace("$$Expire$$", expire.ToString(new NumberFormatInfo())));
            //}

            // also clear all entries for this host from availPool
            ClearHostFromPool(_availPool, host);
        }
        else
        {
            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug(GetLocalizedString("created socket").Replace("$$ToString$$", socket.ToString()).Replace("$$Host$$", host));
            //}
            _hostDead.Remove(host);
            _hostDeadDuration.Remove(host);
            if (_buckets.BinarySearch(host) < 0)
            {
                _buckets.Add(host);
            }
        }

        return(socket);
    }
Exemplo n.º 21
0
    public void Initialize()
    {
        // check to see if already initialized
        if (_initialized &&
            _buckets != null &&
            _availPool != null &&
            _busyPool != null)
        {
            //if(Log.IsErrorEnabled)
            //{
            //    Log.Error(GetLocalizedString("initializing initialized pool"));
            //}
            return;
        }

        // initialize empty maps
        _buckets          = new ArrayList();
        _availPool        = new Hashtable(_servers.Count * _initConns);
        _busyPool         = new Hashtable(_servers.Count * _initConns);
        _hostDeadDuration = new Hashtable();
        _hostDead         = new Hashtable();
        _createShift      = new Hashtable();
        _maxCreate        = (_poolMultiplier > _minConns) ? _minConns : _minConns / _poolMultiplier;    // only create up to maxCreate connections at once

        //if(Log.IsDebugEnabled)
        //{
        //    Log.Debug(GetLocalizedString("initializing pool")
        //        .Replace("$$InitConnections$$", InitConnections.ToString(new NumberFormatInfo()))
        //        .Replace("$$MinConnections$$", MinConnections.ToString(new NumberFormatInfo()))
        //        .Replace("$$MaxConnections$$", MaxConnections.ToString(new NumberFormatInfo())));
        //}

        // if servers is not set, or it empty, then
        // throw a runtime exception
        if (_servers == null || _servers.Count <= 0)
        {
            //if(Log.IsErrorEnabled)
            //{
            //    Log.Error(GetLocalizedString("initialize with no servers"));
            //}
            throw new ArgumentException(GetLocalizedString("initialize with no servers"));
        }

        for (int i = 0; i < _servers.Count; i++)
        {
            // add to bucket
            // with weights if we have them
            if (_weights != null && _weights.Count > i)
            {
                for (int k = 0; k < ((int)_weights[i]); k++)
                {
                    _buckets.Add(_servers[i]);
                    //if(Log.IsDebugEnabled)
                    //{
                    //    Log.Debug("Added " + _servers[i] + " to server bucket");
                    //}
                }
            }
            else
            {
                _buckets.Add(_servers[i]);
                //if(Log.IsDebugEnabled)
                //{
                //    Log.Debug("Added " + _servers[i] + " to server bucket");
                //}
            }

            // create initial connections
            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug(GetLocalizedString("create initial connections").Replace("$$InitConns$$", InitConnections.ToString(new NumberFormatInfo())).Replace("$$Servers[i]$$", Servers[i].ToString()));
            //}

            for (int j = 0; j < _initConns; j++)
            {
                SockIO socket = CreateSocket((string)_servers[i]);
                if (socket == null)
                {
                    //if(Log.IsErrorEnabled)
                    //{
                    //    Log.Error(GetLocalizedString("failed to connect").Replace("$$Servers[i]$$", Servers[i].ToString()).Replace("$$j$$", j.ToString(new NumberFormatInfo())));
                    //}
                    break;
                }

                AddSocketToPool(_availPool, (string)_servers[i], socket);
                //if(Log.IsDebugEnabled)
                //{
                //    Log.Debug(GetLocalizedString("created and added socket").Replace("$$ToString$$", socket.ToString()).Replace("$$Servers[i]$$", Servers[i].ToString()));
                //}
            }
        }

        // mark pool as initialized
        _initialized = true;

        // start maint thread TODO: re-enable
        if (_maintThreadSleep > 0)
        {
            this.StartMaintenanceThread();
        }
    }
Exemplo n.º 22
0
    protected void SelfMaintain()
    {
        //if(Log.IsDebugEnabled)
        //{
        //    Log.Debug(GetLocalizedString("start self maintenance"));
        //}

        // go through avail sockets and create/destroy sockets
        // as needed to maintain pool settings
        foreach (string host in new IteratorIsolateCollection(_availPool.Keys))
        {
            Hashtable sockets = (Hashtable)_availPool[host];
            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug(GetLocalizedString("size of available pool").Replace("$$Host$$", host).Replace("$$Sockets$$", sockets.Count.ToString(new NumberFormatInfo())));
            //}

            // if pool is too small (n < minSpare)
            if (sockets.Count < _minConns)
            {
                // need to create new sockets
                int need = _minConns - sockets.Count;
                //if(Log.IsDebugEnabled)
                //{
                //    Log.Debug(GetLocalizedString("need to create new sockets").Replace("$$Need$$", need.ToString(new NumberFormatInfo())).Replace("$$Host$$", host));
                //}

                for (int j = 0; j < need; j++)
                {
                    SockIO socket = CreateSocket(host);

                    if (socket == null)
                    {
                        break;
                    }

                    AddSocketToPool(_availPool, host, socket);
                }
            }
            else if (sockets.Count > _maxConns)
            {
                // need to close down some sockets
                int diff        = sockets.Count - _maxConns;
                int needToClose = (diff <= _poolMultiplier)
                    ? diff
                    : (diff) / _poolMultiplier;

                //if(Log.IsDebugEnabled)
                //{
                //    Log.Debug(GetLocalizedString("need to remove spare sockets").Replace("$$NeedToClose$$", needToClose.ToString(new NumberFormatInfo()).Replace("$$Host$$", host)));
                //}
                foreach (SockIO socket in new IteratorIsolateCollection(sockets.Keys))
                {
                    if (needToClose <= 0)
                    {
                        break;
                    }

                    // remove stale entries
                    DateTime expire = (DateTime)sockets[socket];

                    // if past idle time
                    // then close socket
                    // and remove from pool
                    if ((expire.AddMilliseconds(_maxIdle)) < DateTime.Now)
                    {
                        //if(Log.IsDebugEnabled)
                        //{
                        //    Log.Debug(GetLocalizedString("removing stale entry"));
                        //}
                        try
                        {
                            socket.TrueClose();
                        }
                        catch//(IOException ioe)
                        {
                            //if(Log.IsErrorEnabled)
                            //{
                            //    Log.Error(GetLocalizedString("failed to close socket"), ioe);
                            //}
                        }

                        sockets.Remove(socket);
                        needToClose--;
                    }
                }
            }

            // reset the shift value for creating new SockIO objects
            _createShift[host] = 0;
        }

        // go through busy sockets and destroy sockets
        // as needed to maintain pool settings
        foreach (string host in _busyPool.Keys)
        {
            Hashtable sockets = (Hashtable)_busyPool[host];
            //if(Log.IsDebugEnabled)
            //{
            //    Log.Debug(GetLocalizedString("size of busy pool").Replace("$$Host$$", host).Replace("$$Sockets$$", sockets.Count.ToString(new NumberFormatInfo())));
            //}

            // loop through all connections and check to see if we have any hung connections
            foreach (SockIO socket in new IteratorIsolateCollection(sockets.Keys))
            {
                // remove stale entries
                DateTime hungTime = (DateTime)sockets[socket];

                // if past max busy time
                // then close socket
                // and remove from pool
                if ((hungTime.AddMilliseconds(_maxBusyTime)) < DateTime.Now)
                {
                    //if(Log.IsErrorEnabled)
                    //{
                    //    Log.Error(GetLocalizedString("removing hung connection").Replace("$$Time$$", (new TimeSpan(DateTime.Now.Ticks - hungTime.Ticks).TotalMilliseconds).ToString(new NumberFormatInfo())));
                    //}
                    try
                    {
                        socket.TrueClose();
                    }
                    catch//(IOException ioe)
                    {
                        //if(Log.IsErrorEnabled)
                        //{
                        //    Log.Error(GetLocalizedString("failed to close socket"), ioe);
                        //}
                    }

                    sockets.Remove(socket);
                }
            }
        }

        //if(Log.IsDebugEnabled)
        //{
        //    Log.Debug(GetLocalizedString("end self maintenance"));
        //}
    }
Exemplo n.º 23
0
        /// <summary>
        /// Creates a new SockIO obj for the given server.
        ///
        ///If server fails to connect, then return null and do not try
        ///again until a duration has passed.  This duration will grow
        ///by doubling after each failed attempt to connect.
        /// </summary>
        /// <param name="host">host:port to connect to</param>
        /// <returns>SockIO obj or null if failed to create</returns>
        protected SockIO CreateSocket(string host)
        {
            SockIO socket = null;

            // if host is dead, then we don't need to try again
            // until the dead status has expired
            // we do not try to put back in if failover is off
            if (_failover && _hostDead.ContainsKey(host) && _hostDeadDuration.ContainsKey(host))
            {

                DateTime store = (DateTime)_hostDead[host];
                long expire = ((long)_hostDeadDuration[host]);

                if ((store.AddMilliseconds(expire)) > DateTime.Now)
                    return null;
            }

            try
            {
                socket = new SockIO(this, host, _socketTimeout, _socketConnectTimeout, _nagle);

                if (!socket.IsConnected)
                {
                    if (Log.IsErrorEnabled)
                    {
                        Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host));
                    }
                    try
                    {
                        socket.TrueClose();
                    }
                    catch (SocketException ex)
                    {
                        if (Log.IsErrorEnabled)
                        {
                            Log.Error(GetLocalizedString("failed to close socket on host").Replace("$$Host$$", host), ex);
                        }
                        socket = null;
                    }
                }
            }
            catch (SocketException ex)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host), ex);
                }
                socket = null;
            }
            catch (ArgumentException ex)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host), ex);
                }
                socket = null;
            }
            catch (IOException ex)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error(GetLocalizedString("failed to get socket").Replace("$$Host$$", host), ex);
                }
                socket = null;
            }

            // if we failed to get socket, then mark
            // host dead for a duration which falls off
            if (socket == null)
            {
                DateTime now = DateTime.Now;
                _hostDead[host] = now;
                long expire = (_hostDeadDuration.ContainsKey(host)) ? (((long)_hostDeadDuration[host]) * 2) : 100;
                _hostDeadDuration[host] = expire;
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(GetLocalizedString("ignoring dead host").Replace("$$Host$$", host).Replace("$$Expire$$", expire.ToString(new NumberFormatInfo())));
                }

                // also clear all entries for this host from availPool
                ClearHostFromPool(_availPool, host);
            }
            else
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(GetLocalizedString("created socket").Replace("$$ToString$$", socket.ToString()).Replace("$$Host$$", host));
                }
                _hostDead.Remove(host);
                _hostDeadDuration.Remove(host);
                if (_buckets.BinarySearch(host) < 0)
                    _buckets.Add(host);
            }

            return socket;
        }
Exemplo n.º 24
0
        public void CheckIn(SockIO socket, bool addToAvail)
        {
            if (socket == null)
                return;

            string host = socket.Host;
            if (Log.IsDebugEnabled)
            {
                Log.Debug("Calling check-in on socket: " + socket.ToString() + " for host: " + host);
            }

            // remove from the busy pool
            if (Log.IsDebugEnabled)
            {
                Log.Debug("Removing socket (" + socket.ToString() + ") from busy pool for host: " + host);
            }
            RemoveSocketFromPool(_busyPool, host, socket);

            // add to avail pool
            if (addToAvail && socket.IsConnected)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("Returning socket (" + socket.ToString() + " to avail pool for host: " + host);
                }
                AddSocketToPool(_availPool, host, socket);
            }
        }
Exemplo n.º 25
0
 public Task Disconnect()
 {
     return(SockIO.DisconnectAsync());
 }
Exemplo n.º 26
0
 public bool IsConnected()
 {
     return(SockIO.GetState() == WebSocketState.Open);
 }
Exemplo n.º 27
0
 public void Dispose()
 {
     SockIO.Dispose();
     StorageProvider.Save();
 }
Exemplo n.º 28
0
 /// <summary>
 /// Removes a socket from specified pool for host.
 /// 
 /// Internal utility method. 
 /// </summary>
 /// 
 /// <param name="pool">pool to remove from</param>
 /// <param name="host">host pool</param>
 /// <param name="socket">socket to remove</param>
 private void RemoveSocketFromPool(IDictionary pool, string host, SockIO socket)
 {
     lock (this)
     {
         if (pool.Contains(host))
         {
             IDictionary sockets = (IDictionary) pool[host];
             if (sockets != null)
             {
                 sockets.Remove(socket);
             }
         }
     }
 }
Exemplo n.º 29
0
        /// <summary>
        /// Adds a socket to a given pool for the given host.
        /// 
        /// Internal utility method. 
        /// </summary>
        /// 
        /// <param name="pool">pool to add to</param>
        /// <param name="host">host this socket is connected to</param>
        /// <param name="socket">socket to add</param>
        private void AddSocketToPool(IDictionary pool, string host, SockIO socket)
        {
            lock (this)
            {

                if (pool.Contains(host))
                {
                    IDictionary sockets = (IDictionary) pool[host];
                    if (sockets != null)
                    {
                        sockets.Add(socket, (long) ((DateTime.Now.Ticks - 621355968000000000) / 10000));
                        return ;
                    }
                }

                IDictionary sockets2 = Hashtable.Synchronized(new Hashtable());
                sockets2.Add(socket, (long) ((DateTime.Now.Ticks - 621355968000000000) / 10000));
                pool.Add(host, sockets2);
            }
        }
Exemplo n.º 30
0
 /// <summary>
 /// Returns a socket to the avail pool.
 /// 
 /// This is called from SockIO.close().  Calling this method<br/>
 /// directly without closing the SockIO object first<br/>
 /// will cause an IOException to be thrown.
 /// </summary>
 /// 
 /// <param name="socket">socket to return</param>
 public virtual void CheckIn(SockIO socket)
 {
     lock (this)
     {
         CheckIn(socket, true);
     }
 }
Exemplo n.º 31
0
 public void CheckIn(SockIO socket)
 {
     CheckIn(socket, true);
 }
Exemplo n.º 32
0
        /// <summary> Creates a new SockIO obj for the given server.
        /// 
        /// If server fails to connect, then return null and do not try<br/>
        /// again until a duration has passed.  This duration will grow<br/>
        /// by doubling after each failed attempt to connect. 
        /// </summary>
        /// 
        /// <param name="host">host:port to connect to</param>
        /// <returns>SockIO obj or null if failed to create</returns>
        private SockIO CreateSocket(string host)
        {
            SockIO socket = null;

            // if host is dead, then we don't need to try again
            // until the dead status has expired
            if (hostDead.Contains(host) && hostDeadDur.Contains(host))
            {
                DateTime store = (DateTime) hostDead[host];
                long expire = ((long) hostDeadDur[host]);

                if ((store.Ticks + expire) > (DateTime.Now.Ticks - 621355968000000000) / 10000)
                    return null;
            }

            try
            {
                socket = new SockIO(host, this.socketTO, this.nagle);

                if (!socket.Connected)
                {
                    if(log.IsErrorEnabled) log.Error("failed to get SockIO obj for: " + host + " -- new socket is not connected");
                    try
                    {
                        socket.TrueClose();
                    }
                    catch(Exception ex)
                    {
                        if(log.IsErrorEnabled) log.Error("failed to close SockIO obj for server: " + host, ex);

                        socket = null;
                    }
                }
            }
            catch(Exception ex)
            {
                if(log.IsErrorEnabled) log.Error("failed to get SockIO obj for: " + host, ex);
            }

            // if we failed to get socket, then mark
            // host dead for a duration which falls off
            if (socket == null)
            {
                DateTime now = DateTime.Now;
                hostDead.Add(host, now);
                long expire = (hostDeadDur.Contains(host))?((long) ((long) hostDeadDur[host]) * 2):1000;
                hostDeadDur.Add(host, (long) expire);
                if(log.IsDebugEnabled) log.Debug("Ignoring dead host: " + host + " for " + expire + " ms");

                // also clear all entries for this host from availPool
                ClearHostFromPool(availPool, host);
            }
            else
            {
                if(log.IsDebugEnabled) log.Debug("Created socket (" + socket.GetHashCode() + ") for host: " + host);
                hostDead.Remove(host);
                hostDeadDur.Remove(host);
            }

            return socket;
        }
Exemplo n.º 33
0
        /// <summary>
        /// This method loads the data from cache into a Hashtable.
        /// 
        /// Pass a SockIO object which is ready to receive data and a Hashtable
        /// to store the results.
        /// </summary>
        /// <param name="sock">socket waiting to pass back data</param>
        /// <param name="hm">hashmap to store data into</param>
        /// <param name="asString">if true, and if we are using NativehHandler, return string val</param>
        private void LoadItems(SockIO sock, Hashtable hm, bool asString)
        {
            while (true)
            {
                string line = sock.ReadLine();
                if (log.IsDebugEnabled)
                {
                    log.Debug(GetLocalizedString("loaditems line").Replace("$$Line$$", line));
                }

                if (line.StartsWith(VALUE))
                {
                    string[] info = line.Split(' ');
                    string key = info[1];
                    int flag = int.Parse(info[2], new NumberFormatInfo());
                    int length = int.Parse(info[3], new NumberFormatInfo());

                    if (log.IsDebugEnabled)
                    {
                        log.Debug(GetLocalizedString("loaditems header").Replace("$$Key$$", key).Replace("$$Flags$$", flag.ToString(new NumberFormatInfo())).Replace("$$Length$$", length.ToString(new NumberFormatInfo())));
                    }

                    // read obj into buffer
                    byte[] buf = new byte[length];
                    sock.Read(buf);
                    sock.ClearEndOfLine();

                    // ready object
                    object o;

                    // check for compression
                    if ((flag & F_COMPRESSED) != 0)
                    {
                        try
                        {
                            // read the input stream, and write to a byte array output stream since
                            // we have to read into a byte array, but we don't know how large it
                            // will need to be, and we don't want to resize it a bunch
                            GZipInputStream gzi = new GZipInputStream(new MemoryStream(buf));
                            MemoryStream bos = new MemoryStream(buf.Length);

                            int count;
                            byte[] tmp = new byte[2048];
                            while ((count = gzi.Read(tmp, 0, tmp.Length)) > 0)
                            {
                                bos.Write(tmp, 0, count);
                            }

                            // store uncompressed back to buffer
                            buf = bos.ToArray();
                            gzi.Close();
                        }
                        catch (IOException e)
                        {
                            if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString("loaditems uncompression IOException").Replace("$$Key$$", key), e);
                            }
                            throw new IOException(GetLocalizedString("loaditems uncompression IOException").Replace("$$Key$$", key), e);
                        }
                    }

                    // we can only take out serialized objects
                    if ((flag & F_SERIALIZED) == 0)
                    {
                        if (_primitiveAsString || asString)
                        {
                            // pulling out string value
                            if (log.IsInfoEnabled)
                            {
                                log.Info(GetLocalizedString("loaditems retrieve as string"));
                            }
                            o = Encoding.GetEncoding(_defaultEncoding).GetString(buf);
                        }
                        else
                        {
                            // decoding object
                            try
                            {
                                o = NativeHandler.Decode(buf);
                            }
                            catch (Exception e)
                            {
                                if (log.IsErrorEnabled)
                                {
                                    log.Error(GetLocalizedString("loaditems deserialize error").Replace("$$Key$$", key), e);
                                }
                                throw new IOException(GetLocalizedString("loaditems deserialize error").Replace("$$Key$$", key), e);
                            }
                        }
                    }
                    else
                    {
                        // deserialize if the data is serialized
                        try
                        {
                            MemoryStream memStream = new MemoryStream(buf);
                            o = new BinaryFormatter().Deserialize(memStream);
                            if (log.IsInfoEnabled)
                            {
                                log.Info(GetLocalizedString("loaditems deserializing").Replace("$$Class$$", o.GetType().Name));
                            }
                        }
                        catch (SerializationException e)
                        {
                            if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString("loaditems SerializationException").Replace("$$Key$$", key), e);
                            }
                            throw new IOException(GetLocalizedString("loaditems SerializationException").Replace("$$Key$$", key), e);
                        }
                    }

                    // store the object into the cache
                    hm[key] = o;
                }
                else if (END == line)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.Debug(GetLocalizedString("loaditems finished"));
                    }
                    break;
                }
            }
        }