private void CheckAllocateNewInstance() { if (NotifiableSubServerRequirement != null) { lock (lckAllocate) { try { SubServer subServer = NotifiableSubServerRequirement.StartNewInstance(); if (subServer == null) { return; } AddSubServerInternal(subServer, true); Logger.WriteLog("A new server instance was requested to meet the next requests", ServerLogType.ALERT); Thread.Sleep(1000); } catch (Exception ex) { Logger.WriteLog($"Failed to request a new sub-server instance for the implementation of 'NotifiableSubServerRequirement': {ex.Message}", ServerLogType.ERROR); } } } }
private SubServer GetAvailableSubServer() { lock (lckGtAvlb) { for (int i = 0; i < SubServers.Count; i++) { if (selectedSubServerIndex >= SubServers.Count) { selectedSubServerIndex = 0; } SubServer server = SubServers[selectedSubServerIndex]; if (IsServerUnavailable(server)) { continue; } string key = $"unavailable-{server.Address}:{server.Port}"; if (!CanOperate(key, server)) { continue; } selectedSubServerIndex += 1; return(server); } return(null); } }
private bool IsServerUnavailable(SubServer server) { string key = $"unavailable-{server.Address}:{server.Port}"; Cache <bool> cached = CacheRepository <bool> .Get(key); if (cached != null) { Logger.WriteLog($"The sub-server node '{server.Address}:{server.Port}' is unreachable. It is temporarily ignored but will be reconsidered in less than 120 seconds", ServerLogType.ALERT); } return(cached != null); }
private int GetCurrentThreadCountOnServer(SubServer server) { using (ISocketClientConnection client = BuildClient(server)) { Logger.WriteLog($"Querying availability on '{server.Address}:{server.Port}'", ServerLogType.INFO); client.SendRequest("ServerInfoController", "GetCurrentThreadsCount"); int result = int.Parse(client.GetResult().Entity.ToString()); return(result); } }
public static void AddSubServer(string address, int port, Encoding encoding, int maxConnectionAttempts, int acceptableProcesses) { if (SubServers == null) { SubServers = new List <SubServer>(); } var server = new SubServer(address, port, encoding, maxConnectionAttempts, acceptableProcesses); AddSubServerInternal(server); }
private bool AreServerConnected(SubServer server, string cacheKey) { try { using (ISocketClientConnection client = BuildClient(server)) return(true); } catch { Logger.WriteLog($"Sub-server node '{server.Address}:{server.Port}' is unreachable", ServerLogType.ALERT); CacheRepository <bool> .Set(cacheKey, true, 120); return(false); } }
private ISocketClientConnection BuildClient(SubServer server) { try { return(SocketConnectionFactory.GetConnection(new SocketClientSettings( server: server.Address, port: server.Port, encoding: server.Encoding, maxAttempts: server.MaxConnectionAttempts ))); } catch (Exception ex) { Logger.WriteLog($"Fail to connect server {server.Address}:{server.Port} : {ex.Message}", ServerLogType.ERROR); return(null); } }
public ActionResult RunAction(string receivedData) { SocketAppServerClient.RequestBody rb = JsonConvert.DeserializeObject <SocketAppServerClient.RequestBody>(receivedData, AppServerConfigurator.SerializerSettings); if (rb.Controller.Equals("ServerInfoController") && rb.Action.Equals("FullServerInfo")) { return(new ServerInfoController().FullServerInfo()); } string cacheResultKey = BuildCacheResultKey(rb); SubServer targetServer = GetAvailableSubServer(); if (targetServer == null) { CheckAllocateNewInstance(); if (retried) { return(ResolveResultOnUreachableServer(cacheResultKey)); } else { retried = true; return(RunAction(receivedData)); } } using (ISocketClientConnection client = BuildClient(targetServer)) { client.SendRequest(rb); SocketAppServerClient.OperationResult result = client.GetResult(); if (EnabledCachedResultsForUnreachableServers) { CacheRepository <SocketAppServerClient.OperationResult> .Set(cacheResultKey, result, 380); } targetServer.RefreshLifetimeIfHas(); return(ActionResult.Json(result)); } }
private static void AddSubServerInternal(SubServer server, bool isDynamicInstance = false) { if (Logger == null) { Logger = ServiceManager.GetInstance().GetService <ILoggingService>(); } SubServers.Add(server); if (SubServers.Count > 1) { if (isDynamicInstance) { if (NotifiableSubServerRequirement != null) { server.EnableLifetime(NotifiableSubServerRequirement, ServersLifetimeInMinutes); server.OnLifeTimeEnded += SubServer_OnLifeTimeEnded; } } } Logger.WriteLog($"Added sub-server node named as '{server.Address}:{server.Port}'", ServerLogType.INFO); }
private bool CanOperate(string key, SubServer server) { int serverCurrentThreadsCount; try { serverCurrentThreadsCount = GetCurrentThreadCountOnServer(server); } catch { CacheRepository <bool> .Set(key, true, 120); return(false); } if (serverCurrentThreadsCount > server.AcceptableProcesses) { Logger.WriteLog($"Sub-server node '{server.Address}:{server.Port}' is too busy", ServerLogType.ALERT); return(false); } return(true); }
private static void SubServer_OnLifeTimeEnded(SubServer subServer) { Logger.WriteLog($"Sub-server '{subServer.Address}:{subServer.Port}' is no longer needed and will be detached from the pool of sub-servers. A notification was issued for the target sub-server to be shut down", ServerLogType.ALERT); SubServers.Remove(subServer); }