#include "StdAfx.h"
#include "OverloadManager.h"

#define	CLASS_NAME	_U8("OverloadManager")

COverloadManager::COverloadManager(void)
{
}

COverloadManager::~COverloadManager(void)
{
}

/*!
	初期化
*/
void COverloadManager::Start(CIServerToolWrap serverTool, int maxConnect, int overloadModeKeepTime)
{
	m_serverTool = serverTool;
	m_maxConnect = maxConnect;
	m_overloadModeKeepTime = overloadModeKeepTime;
	m_overload = 0;

	//	エントリを生成しておく
	m_serverTool.SetServerStatusInt(_U8("ConnectionCount"),			0, _U16("現在の接続数"));
	m_serverTool.SetServerStatusInt(_U8("ThreadCount"),				0, _U16("現在のスレッド数"));
	m_serverTool.SetServerStatusInt(_U8("QueueingConnectionCount"),	0, _U16("現在の処理待ち接続数"));
	m_serverTool.SetServerStatusInt(_U8("OverloadMode"),			0, _U16("オーバーロード"));
}


/*!
	サーバ負荷を設定
*/
void COverloadManager::UpdateServerload(int threadCount, int queueCount)
{
	CRITICAL_SECTION_SCOPE();

	//	現在の接続数
	int curConnectionCount = threadCount + queueCount;

	//	オーバーロード？
	if(curConnectionCount >= m_maxConnect)
	{
		//	オーバーロード中
		if(!m_overload)
		{
			m_serverTool.WriteSystemLog(CLASS_NAME, SYSTEM_LOG_WARNING, _U16("オーバーロードモードへ移行しました"));
			m_serverTool.NotifyServerMessage(_U8("OverloadMode"), _U16("オーバーロードモードで実行中です"), SYSTEM_MESSAGE_WARNING);
		}

		m_overloadModeStartTime = GetTickCount();
		m_overload = TRUE;
	}
	else
	{
		//	オーバーロード解除？
		if(m_overload && IsOver(m_overloadModeStartTime, GetTickCount(), m_overloadModeKeepTime))
		{
			m_serverTool.NotifyServerMessage(_U8("OverloadMode"), _U16("オーバーロードモードから復帰しました"), SYSTEM_MESSAGE_INFO, 3600);
			m_overload = FALSE;
		}
	}

	//	情報更新
	m_serverTool.SetServerStatusInt(_U8("ConnectionCount"),			curConnectionCount);
	m_serverTool.SetServerStatusInt(_U8("ThreadCount"),				threadCount);
	m_serverTool.SetServerStatusInt(_U8("QueueingConnectionCount"),	queueCount);
	m_serverTool.SetServerStatusInt(_U8("OverloadMode"),				m_overload);
}

/*!
	指定時間過ぎたか？
*/
int COverloadManager::IsOver(DWORD old, DWORD cur, DWORD span)
{
	//	48日過ぎた？
	if(old > cur)
		return(TRUE);

	//	経過
	if(old + span < cur)
		return(TRUE);

	return(FALSE);
}

