Пример #1
0
        /// <summary>
        /// Queue initial heartbeats to active servers
        /// </summary>
        public void QueueInitialHeartbeats()
        {
            DateTime Now = DateTime.UtcNow;
            uint     HeartbeatsStarted = 0;

            lock (ActiveServerTable)
            {
                foreach (var Pair in ActiveServerTable)
                {
                    NWGameServer Server = Pair.Value;

                    lock (Server)
                    {
                        if (!Server.Online)
                        {
                            continue;
                        }

                        Server.InitialHeartbeat = true;
                        Server.StartHeartbeat();
                        HeartbeatsStarted += 1;
                    }
                }
            }

            Logger.Log(LogLevel.Normal, "NWServerTracker.QueueInitialHeartbeats(): Queued {0} initial server heartbeat requests.", HeartbeatsStarted);

            PendingGameServersSweepTimer.Start();
            ScavengerSweepTimer.Start();
            BlacklistSweepTimer.Start();
        }
Пример #2
0
        /// <summary>
        /// This method disables future heartbeats and flushes any servers that
        /// may be in the heartbeat path out of that code path before further
        /// forward progress is allowed.
        /// </summary>
        public void DrainHeartbeats()
        {
            //
            // Prevent new requestors from spinning up new heartbeat requests.
            //

            HeartbeatsEnabled = false;

            //
            // Flush any in-flight requestors out of the heartbeat path by
            // ensuring that they have released synchronization.
            //

            Monitor.Enter(HeartbeatLock);
            Monitor.Exit(HeartbeatLock);

            //
            // Stop all of the active timers.  New timers that have elapsed
            // will have already completed starting the timer again or will now
            // observe that future timer restarts are already forbidden.
            //

            PendingGameServersSweepTimer.Stop();
            ScavengerSweepTimer.Stop();
            BlacklistSweepTimer.Stop();
        }
Пример #3
0
        /// <summary>
        /// This timer callback runs when the pending game servers sweep timer
        /// elapses.  It checks whether there is a pending query queue, and if
        /// so, flushes it as appropriate.
        /// </summary>
        /// <param name="sender">Unused.</param>
        /// <param name="e">Unused.</param>
        private void PendingGameServersSweepTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                uint   HighestPendingServerId = 0;
                bool   DataReturned           = false;
                string Query = String.Format(
                    @"SELECT `pending_game_server_id`, 
    `server_address` 
FROM 
    `pending_game_servers` 
WHERE 
    `product_id` = {0} 
GROUP BY `pending_game_server_id` 
ORDER BY `pending_game_server_id` 
LIMIT 100 ",
                    MasterServer.ProductID);

                using (MySqlDataReader Reader = MasterServer.ExecuteQuery(Query))
                {
                    while (Reader.Read())
                    {
                        uint       PendingServerId = Reader.GetUInt32(0);
                        string     Hostname        = Reader.GetString(1);
                        IPEndPoint ServerAddress;

                        if (PendingServerId > HighestPendingServerId)
                        {
                            HighestPendingServerId = PendingServerId;
                        }

                        if (DataReturned == false)
                        {
                            DataReturned = true;
                        }

                        ServerAddress = ConvertServerHostnameToIPEndPoint(Hostname);
                        if (ServerAddress == null)
                        {
                            Logger.Log(LogLevel.Error, "NWServerTracker.PendingGameServersSweepTimer_Elapsed(): Server {0} has invalid hostname '{1}'.",
                                       PendingServerId,
                                       Hostname);
                            continue;
                        }

                        NWGameServer Server = LookupServerByAddress(ServerAddress, false);

                        if (Server == null || Server.Online == false)
                        {
                            MasterServer.SendServerInfoRequest(ServerAddress);
                        }
                    }
                }

                if (DataReturned)
                {
                    //
                    // Remove records that have already been processed.
                    //

                    MasterServer.ExecuteQueryNoReader(String.Format(
                                                          @"DELETE FROM 
    `pending_game_servers` 
WHERE 
    `product_id` = {0} 
AND 
    `pending_game_server_id` < {1}",
                                                          MasterServer.ProductID,
                                                          HighestPendingServerId + 1));
                }
            }
            catch (Exception ex)
            {
                Logger.Log(LogLevel.Error, "NWServerTracker.PendingGameServersSweepTimer_Elapsed(): Exception processing pending servers list: {0}.", ex);
            }

            lock (HeartbeatLock)
            {
                if (!HeartbeatsEnabled)
                {
                    return;
                }

                PendingGameServersSweepTimer.Start();
            }
        }