초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Xml.Linq;
namespace ServerCore;
//=============================================================================================
// 주기적 Task 타이머 클래스 이다.
//
// author : kangms
//
//=============================================================================================
public class PeriodicTaskTimer : IAsyncDisposable
{
private readonly string m_name;
private readonly System.Threading.PeriodicTimer m_timer;
private readonly Task m_timer_task;
private readonly CancellationTokenSource m_cts;
public delegate Task FnFunction();
private readonly FnFunction m_fn_alarm_function;
public PeriodicTaskTimer(string name, Int32 intervalSec, FnFunction fnAlarmFunction)
{
m_name = name;
m_cts = new CancellationTokenSource();
m_timer = new System.Threading.PeriodicTimer(TimeSpan.FromSeconds(intervalSec));
m_fn_alarm_function = fnAlarmFunction;
m_timer_task = handleTimerAsync(m_timer, m_cts.Token);
}
//=============================================================================================
// CancellationTokenSource 를 외부에서 제어할 때 사용한다.
//=============================================================================================
public PeriodicTaskTimer(string name, double intervalMSec, CancellationTokenSource cts, FnFunction fnAlarmFunction)
{
m_name = name;
m_cts = cts;
m_timer = new System.Threading.PeriodicTimer(TimeSpan.FromMilliseconds(intervalMSec));
m_fn_alarm_function = fnAlarmFunction;
m_timer_task = handleTimerAsync(m_timer, m_cts.Token);
}
private async Task handleTimerAsync(System.Threading.PeriodicTimer timer, CancellationToken cancel = default)
{
try
{
while (await timer.WaitForNextTickAsync(cancel))
{
await Task.Run(() => m_fn_alarm_function.Invoke());
}
}
catch (OperationCanceledException e)
{
var msg = $"PeriodicTaskTimer cancel Operation !!! : exception:{e} - {m_name}";
Log.getLogger().info(msg);
}
catch (Exception e)
{
var err_msg = $"PeriodicTaskTimer exception !!! : exception:{e} - {m_name}";
Log.getLogger().error(err_msg);
}
}
public void cancelTimer() => m_cts.Cancel();
//for IAsyncDisposable.DisposeAsync()
public async ValueTask DisposeAsync()
{
m_timer.Dispose();
await m_timer_task;
GC.SuppressFinalize(this);
}
public System.Threading.PeriodicTimer getPeriodicTimer() => m_timer;
public Task getTask() => m_timer_task;
}
//=============================================================================================
// 주기적 Task 타이머 지원 클래스 이다.
//
// author : kangms
//
//=============================================================================================
public static class PeriodicTaskHelper
{
public static async Task runTask(Func<Task> action, TimeSpan interval, CancellationToken cancellationToken = default)
{
using var timer = new PeriodicTimer(interval);
while (cancellationToken.IsCancellationRequested == false)
{
try
{
await action();
await timer.WaitForNextTickAsync(cancellationToken);
}
catch (OperationCanceledException e)
{
var msg = $"PeriodicTaskHelper cancel Operation !!! : Msg:{e.Message}";
Log.getLogger().info(msg);
break;
}
catch (Exception e)
{
var err_msg = $"PeriodicTaskHelper exception !!! : errMsg:{e.Message}";
Log.getLogger().error(err_msg);
throw;
}
}
}
public static void bindToTasks(this PeriodicTaskTimer taskTimer, List<Task> tasks)
{
tasks.Add(taskTimer.getTask());
}
}

View File

@@ -0,0 +1,243 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore;
//=============================================================================================
// 간단한 로직을 위한 타이머 클래스 이다.
//
// author : kangms
//
//=============================================================================================
public class SimpleTimer
{
private DateTime m_begin_timestamp = DateTime.MinValue;
private DateTime m_end_timestamp = DateTime.MinValue;
private Int64 m_time_limit_msec = 0;
private bool m_is_paused = false;
private DateTime m_pause_timestamp = new DateTime();
private Int64 m_pause_total_msec = 0;
private bool m_active = false;
public SimpleTimer()
{
}
public SimpleTimer(Int64 timeLimitMSec)
{
setTimeLimitMSec(timeLimitMSec);
}
public void setTimer(Int64 timeLimitMSec)
{
setTimer(0, timeLimitMSec);
}
public void setTimer(Int64 beginUtcTick, Int64 timeLimitMSec)
{
m_begin_timestamp = beginUtcTick > 0 ? new DateTime(beginUtcTick) : DateTime.UtcNow;
m_time_limit_msec = timeLimitMSec;
m_is_paused = false;
m_pause_total_msec = 0;
m_end_timestamp = DateTime.MinValue;
}
public void activate(Int64 timeLimitMSec = 0)
{
m_active = true;
if (timeLimitMSec != 0)
{
setTimer(0, timeLimitMSec);
}
else
{
reset(0);
}
}
public void activate(Int64 beginUtcTick, Int64 timeLimitMSec = 0)
{
m_active = true;
if (timeLimitMSec != 0)
{
setTimer(beginUtcTick, timeLimitMSec);
}
else
{
reset(beginUtcTick);
}
}
public bool isActive()
{
return m_active;
}
public void deactivate()
{
m_active = false;
m_end_timestamp = DateTime.UtcNow;
}
public void setTimeLimitMSec(Int64 limitMSec)
{
m_time_limit_msec = limitMSec;
m_time_limit_msec = Math.Max(m_time_limit_msec, 0);
}
public void incTimeLimitMSec(Int64 incMSec)
{
m_time_limit_msec += incMSec;
m_time_limit_msec = Math.Max(m_time_limit_msec, 0);
}
public Int64 getTimeLimitMSec()
{
return m_time_limit_msec;
}
public void reset()
{
setTimer(m_time_limit_msec);
}
public void reset(Int64 beginUtcTick)
{
setTimer(beginUtcTick, m_time_limit_msec);
}
public bool expired()
{
if (false == isActive())
{
return false;
}
if (true == isPause())
{
return false;
}
return (DateTime.UtcNow - m_begin_timestamp).TotalMilliseconds > (m_pause_total_msec + m_time_limit_msec);
}
public void pause()
{
if (isPause())
{
return;
}
m_is_paused = true;
m_pause_timestamp = DateTime.UtcNow;
}
public bool isPause()
{
return m_is_paused;
}
public void unpause()
{
if (false == isPause())
{
return;
}
var pause_time = (DateTime.UtcNow - m_pause_timestamp).TotalMilliseconds;
m_pause_total_msec += (Int64)pause_time;
m_is_paused = false;
}
public Int64 getTotalTimeMSec()
{
if (!isActive())
{
return 0;
}
var end_time = m_begin_timestamp.AddMilliseconds(m_time_limit_msec);
var total_time = (end_time - m_begin_timestamp).TotalMilliseconds;
total_time = Math.Max(total_time, 0);
return (Int64)total_time;
}
public Int64 getElapsedPauseTimeMSec()
{
if (false == isActive())
{
return 0;
}
var pause_time = m_pause_total_msec;
if (true == isPause())
{
pause_time += (Int64)((DateTime.UtcNow - m_pause_timestamp).TotalMilliseconds);
}
pause_time = Math.Max(pause_time, 0);
return (Int64)pause_time;
}
public bool isOn()
{
if (false == expired())
{
return false;
}
reset();
return true;
}
public DateTime getStartedTime() => m_begin_timestamp;
public DateTime getEndTime() => m_end_timestamp;
public Int64 getRemainTimeMSec()
{
if (false == isActive())
{
return 0;
}
var pause_time = getElapsedPauseTimeMSec();
TimeSpan time_span = DateTime.UtcNow - m_begin_timestamp;
var remain_time = m_time_limit_msec + pause_time - (Int64)time_span.TotalMilliseconds;
remain_time = Math.Max(remain_time, 0);
return remain_time;
}
public Int64 getElapsedTimeMSec()
{
if (false == isActive())
{
return 0;
}
TimeSpan time_span = DateTime.UtcNow - m_begin_timestamp;
return (Int64)time_span.TotalMilliseconds;
}
}

View File

@@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore;
//=============================================================================================
// StopWatch 모듈을 활용한 타이머 기능을 제공하는 클래스 이다.
//
// author : kangms
//=============================================================================================
public class StopwatchTimer
{
private readonly System.Diagnostics.Stopwatch m_stop_watch = new System.Diagnostics.Stopwatch();
private readonly TimeSpan m_interval = default(TimeSpan);// 체크 주기
private readonly bool m_is_manual_restart = false; // 수동 재시작 여부
private bool m_force_on = false;
public StopwatchTimer(TimeSpan intreval, bool is_pause = false, bool is_manual_restart = false)
{
m_interval = intreval;
m_is_manual_restart = is_manual_restart;
if (is_pause)
{
pause();
}
else
{
resume();
}
}
public StopwatchTimer(Int64 interval_milliseconds, bool is_pause = false, bool is_manual_restart = false)
: this(new TimeSpan(interval_milliseconds * TimeSpan.TicksPerMillisecond), is_pause, is_manual_restart)
{
}
public StopwatchTimer(float intreval_seconds, bool is_pause = false, bool is_manual_restart = false)
: this((Int64)(intreval_seconds * 1000.0f), is_pause, is_manual_restart)
{
}
//=========================================================================================
// 지정된 시간 만큼 경과 되었는지 검사한다.
//=========================================================================================
public bool isOn()
{
if (m_force_on)
{
m_force_on = false;
}
else
{
if (m_stop_watch.IsRunning == false)
{
return false;
}
if (Elapsed < m_interval)
{
return false;
}
}
if (m_is_manual_restart)
{
// 한번만 실행되고 멈춘다, 다시 시작하려면, restart를 호출해야 한다.
pause();
}
else
{
// 자동리셋이면 재시작
restart();
}
return true;
}
// 강제로 타이머를 On상태로 만든다.
public void forceOn()
{
m_force_on = true;
}
//=========================================================================================
// isOn의 기능과, 경과시간을 얻어온다.
//=========================================================================================
public bool isOn(out TimeSpan elapsed)
{
elapsed = Elapsed;
return isOn();
}
//=========================================================================================
// 타이머가 멈춰있는가?
//=========================================================================================
public bool isPaused()
{
return m_stop_watch.IsRunning == false;
}
//=========================================================================================
// 타이머가 실행중인가?
//=========================================================================================
public bool isRunning()
{
return m_stop_watch.IsRunning;
}
//=========================================================================================
// 일시정지
//=========================================================================================
public void pause()
{
m_stop_watch.Stop();
}
//=========================================================================================
// 시작 또는 일시정지를 종료하고 다시 시작
//=========================================================================================
public void resume()
{
m_stop_watch.Start();
}
//=========================================================================================
// 타이머를 초기화하고, 시작
//=========================================================================================
public TimeSpan restart()
{
TimeSpan elapsed = m_stop_watch.Elapsed;
m_stop_watch.Reset();
m_stop_watch.Start();
return elapsed;
}
//=========================================================================================
// 경과 시간 조회
//=========================================================================================
public TimeSpan Elapsed
{
get { return m_stop_watch.Elapsed; }
}
//=========================================================================================
// 남은 시간 조회
//=========================================================================================
public TimeSpan RemainTime
{
get { return Elapsed.TotalSeconds > 0 ? (m_interval > Elapsed ? m_interval - Elapsed : new TimeSpan(0)) : new TimeSpan(0); }
}
}