/// <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(',')); }
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); }
/// <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, ",")); }
/// <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() } }); }
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; }
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)); }
/// <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); }
/// <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; }
/// <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); } } }
public void CheckIn(SockIO socket) { CheckIn(socket, true); }
/// <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; }
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 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); }
/// <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); }
/// <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); }
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(); } }
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")); //} }
/// <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; }
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); } }
public Task Disconnect() { return(SockIO.DisconnectAsync()); }
public bool IsConnected() { return(SockIO.GetState() == WebSocketState.Open); }
public void Dispose() { SockIO.Dispose(); StorageProvider.Save(); }
/// <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); } } } }
/// <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); } }
/// <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); } }
/// <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; }
/// <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; } } }