/// <summary> /// Increase current user /// </summary> public void IncreaseCU() { Interlocked.Increment(ref _CurrUserCount); logger.Debug("server " + Name + " current User Count:" + CurrUserCount); if (CurrUserCount > MAX_CURRUSER) { this.State = ServerState.Busy; logger.Warn("this server state change to busy.CurrentUserCount:" + CurrUserCount); } }
/// <summary> /// get server from server pool /// </summary> /// <returns>return a server minimum of current user </returns> public Server GetServer() { if (ServerPool == null || ServerPool.Count == 0) { return(null); } Server result = null; int currUserCount = -1; int count = ServerPool.Count; Random ran = new Random(); int start = ran.Next(0, count); for (int i = start; i < start + count; i++) { var index = i; if (index >= count) { index -= count; } var server = ServerPool[index]; if (server.State == ServerState.Dead && (DateTime.Now - server.DeadTime) > server.DeadTimeout) { lock (this) { if (server.State == ServerState.Dead && (DateTime.Now - server.DeadTime) > server.DeadTimeout) { result = server; server.State = ServerState.Testing; logger.Debug("find server that need to test!host:" + server.Address); break; } } } else { if ((server.CurrUserCount < currUserCount * server.WeightRate || currUserCount < 0) && server.State == ServerState.Normal ) { currUserCount = server.CurrUserCount; result = server; } } } return(result); }
private void checkSettingsChanges() { try { // ① If the server settings have changed, reinitialize everything. if (reinitialize()) { return; } // ② If a module rewrote its settings, save the settings file. if (_settingsSavedByModule) { _log.Debug("A module saved the settings."); try { lock (_lockObject) CurrentSettings.Save(_settingsPath); } catch (Exception e) { _log.Error("Error saving Propeller settings:"); PropellerUtil.LogException(_log, e); } _settingsSavedByModule = false; _settingsLastChangedTime = File.GetLastWriteTimeUtc(_settingsPath); } // ③ If any module wants to reinitialize, do it AppDomainInfo[] actives; lock (_lockObject) actives = _activeAppDomains.ToArray(); foreach (var active in actives) { if (!active.MustReinitialize) // this adds a log message if it returns true { continue; } _log.Info("Module says it must reinitialize: {0} ({1})".Fmt(active.ModuleSettings.ModuleName, active.GetHashCode())); var newAppDomain = new AppDomainInfo(_log, CurrentSettings, active.ModuleSettings, active.Saver); lock (_lockObject) { _inactiveAppDomains.Add(active); _activeAppDomains.Remove(active); _activeAppDomains.Add(newAppDomain); _server.Handler = createResolver().Handle; _log.Info(" --- {0} replaced with {1}, {0} shutting down".Fmt(active.GetHashCode(), newAppDomain.GetHashCode())); active.RunnerProxy.Shutdown(); } } // ④ Try to clean up as many inactive AppDomains as possible AppDomainInfo[] inactives; lock (_lockObject) inactives = _inactiveAppDomains.ToArray(); foreach (var inactive in inactives) { // Ask the runner if it has active connections; if this throws, it’s in a broken state anyway, so unload it by force. bool disposeAllowed; try { disposeAllowed = inactive.HasActiveConnections; } catch { disposeAllowed = true; } if (disposeAllowed) { _log.Info("Disposing inactive module: {0} ({1})".Fmt(inactive.ModuleSettings.ModuleName, inactive.GetHashCode())); lock (_lockObject) _inactiveAppDomains.Remove(inactive); try { inactive.Dispose(); } catch { } } else { _log.Info("Inactive module still has active connections: {0} ({1})".Fmt(inactive.ModuleSettings.ModuleName, inactive.GetHashCode())); } } } catch (Exception e) { PropellerUtil.LogException(_log, e); } }
public InvokeResult Invoke(Type returnType, string typeName, string methodName, params Parameter[] paras) { logger.Debug("current thread count:" + ThreadCount); if (ThreadCount > config.MaxThreadCount) { logger.Error("server is too busy(" + ThreadCount + ").Service:" + _ServiceName); throw new Exception("server is too busy.(" + _ServiceName + ")"); } try { System.Threading.Interlocked.Increment(ref ThreadCount); Stopwatch watcher = new Stopwatch(); watcher.Start(); List <RpParameter> listPara = new List <RpParameter>(); IList <Type> outParaTypes = new List <Type>(); Array.ForEach(paras, delegate(Parameter p) { listPara.Add(new RpParameter(TypeMapping.ParseType(p.DataType.ToString()), p.Para)); if (p.ParaType == Com.Bj58.Spat.Gaea.Client.Proxy.Enum.ParaType.Out) { outParaTypes.Add(p.DataType); } }); RequestProtocol requestProtocol = new RequestProtocol(typeName, methodName, listPara.ToArray()); byte[] userData = config.Protocol.Serializer.Serialize(requestProtocol); Protocol sendP = new Protocol(config.Protocol, CreateSessionId(), UserDataType.Request, userData); var server = dispatcher.GetServer(); if (server == null) { logger.Error("can't get server"); throw new Exception("can't get server"); } Protocol receiveP = server.Request(sendP);//request server if (receiveP.UserDataType == UserDataType.Response) { var rpGtype = returnType; if (returnType == typeof(void)) { rpGtype = typeof(VOID); } var rpType = typeof(ResponseProtocol <>).MakeGenericType(rpGtype); var rp = config.Protocol.Serializer.Deserialize(receiveP.UserData, rpType); object result = rpType.GetProperty("Result").GetValue(rp, null); object[] outPara = (object[])rpType.GetProperty("Outpara").GetValue(rp, null); logger.Debug("invoke time:" + watcher.ElapsedMilliseconds + "ms"); return(new InvokeResult(result, outPara)); } else if (receiveP.UserDataType == UserDataType.Exception) { var ep = config.Protocol.Serializer.Deserialize <ExceptionProtocol>(receiveP.UserData); throw ExceptionProvider.ThrowServiceError(ep.ErrorCode, ep.ErrorMsg); } else { logger.Error("userdatatype error!"); throw new Exception("userdatatype error!"); } } finally { System.Threading.Interlocked.Decrement(ref ThreadCount); } }
private void Receive() { Stopwatch watcher = new Stopwatch(); watcher.Start(); IList <byte> pData = new List <byte>(); //find start tag byte[] stag = new byte[CONST.P_START_TAG.Length]; Read(stag, 0, CONST.P_START_TAG.Length); if (!ArrayHelper.Equals <byte>(stag, CONST.P_START_TAG)) { while (true) { byte b = (byte)inputStream.ReadByte(); ArrayHelper.LeftMove <byte>(stag, 1); stag[stag.Length - 1] = b; if (ArrayHelper.Equals <byte>(stag, CONST.P_START_TAG)) { break; } } } //read version byte[] bVersion = new byte[SFPStruct.Version]; Read(bVersion, 0, SFPStruct.Version); if (bVersion[0] == 0) { logger.Error("protocol error."); throw new ProtocolException(); } Array.ForEach(bVersion, p => pData.Add(p)); //read total length byte[] bTotalLen = new byte[SFPStruct.TotalLen]; Read(bTotalLen, 0, SFPStruct.TotalLen); Array.ForEach(bTotalLen, p => pData.Add(p)); int totalLen = BitConverter.ToInt32(bTotalLen, 0); //read sessionid byte[] bSessionId = new byte[SFPStruct.SessionId]; Read(bSessionId, 0, SFPStruct.SessionId); Array.ForEach(bSessionId, p => pData.Add(p)); int pSessionId = BitConverter.ToInt32(bSessionId, 0); //read other data byte[] otherData = new byte[totalLen - SFPStruct.Version - SFPStruct.TotalLen - SFPStruct.SessionId]; Read(otherData, 0, otherData.Length); Array.ForEach(otherData, p => pData.Add(p)); //read end tag and check byte[] etag = new byte[CONST.P_END_TAG.Length]; Read(etag, 0, CONST.P_END_TAG.Length); if (!ArrayHelper.Equals(etag, CONST.P_END_TAG)) { throw new Exception("not find end tag from stream!"); } ChannelData channelData; if (ReceiveChannel.TryGetValue(pSessionId, out channelData)) { channelData.Data = pData.ToArray(); channelData.Event.Set(); } logger.Debug("total receive time:" + watcher.ElapsedMilliseconds + "ms"); }