Пример #1
0
        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);
                    }
                }
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
 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);
     }
 }
Пример #8
0
        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));
            }
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
 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);
 }