개인공부) 서버실습(46) - JobTimer

Justin·2022년 7월 27일
0

서버공부

목록 보기
45/45

✅ 지난 시간

지난 시간에는 서버에서 Flush를 Sleep을 0.25초 마다 진행 시켜주었다. 다만 room이 많아지면 각 다른 시간이 될 수 있어 이런 방식으로 처리 할 순 없다.

그렇기에 일감마다의 시간 관리를 해주어야 한다.

틱을 사용하는법

현재 시간과 roomTick이라는 시간을 만들어 둘을 비교하며 현재 실행시킬 지 말지 결정하는 방법이다.

룸에 따라 메인 루프에서 틱을 맞춰서 동작하도록 구성할 수 있다. 다만 메인 루프에서 위와 같이 모든 연산을 처리하는 방법은 관리와 불필요한 연산작업을 하기에 효율적이진 않다.

JobTimer

예약 시스템을 만들어 일정 시간 뒤에 실행하는 방법을 사용해보고자 한다.

위의 코드를 사용하기 위해서는 우선 순위 큐를 사용해야하는데, 강좌 특성상 지난 번에 사용했던 코드를 사용하고자 한다. 하지만 내용이 길어 여기에는 넣지 않겠다.

velog 접기 기능 추가 해주세요..

우선 순위 큐 세팅
Queue 동작 방식을 List로 구현하여 만든 코드를 ServerCore에 두고 사용해야 한다.

JobTimerElem

JobTimerElem를 struct 타입으로 선언하고 IComparable 인터페이스를 상속 받는다.

실행 시간을 계산할 int execTick, 처리 할 업무 action 값을 선언한다.

해당 인터페이스의 필수 구성 요소인 CompareTo()를 통해 받아온 시간 - 실행시간을 하여 더 빠른 순위를 체크한다

JobTimer

해당 클래스를 구성하기 위해 몇가지 요소들을 선언 해준다.

  • PriorityQueue를 JobTimerElem 타입으로 선언
  • lock을 위한 object 선언
  • 사용하기 편하게 하기 위한 JobTimer를 static으로 선언

Push()

Push() 를 만들어 일감을 받기 위한 action, 추가 시간을 위한 int tickAfter = 0; 으로 매개 변수 받기

int tickAfter = 0;을 하는 이유
입력 하지 않으면 0을 대입해 바로 실행시키기 위함

JobTimerElem 타입의 job을 선언 해주고, 여기에 받아온 일감, 시간을 넣어 push 해준다.

Flush()

Pop을 만들 필요는 없고, JobTimer 안에서 일감을 직접 처리 하도록 Flush() 를 구현한다.

무한 루프를 돌며 현재 시각을 받아 오고, JobTimerElem에서 일감을 가지고 와서 lock 안에서 실행시킨다.

단 그 전에 조건을 걸어준다.

일감이 없을 때

if (_pq.Count == 0)
	break;

현재 시간 보다 실행 시간이 많이 남았 때

job = _pq.Peek();
if (job.execTick > now)
	break;

Peek()은 다음으로 으로 실행해야 할 애를 값을 가져오지 않고 어떤 값인지 확인하기 위한 용도이다.

위의 조건들을 모두 통과 했다면 _pq.Pop();을 통해 값을 가져오고 job.action.Invoke(); 일감을 실행시켜 준다.

적용 시키기

서버의 메인 Program에 FlushRoom()이라는 static 함수를 선언하고, 이 안에서 일감을 넣고, 동작을 예약한다.

그 뒤에 메인 루프가 실행되기 전 FlushRoom()을 실행시켜 일감을 넣고, 예약 해준 뒤 루프를 돌며 일감 처리를 한다.

이렇게 해주면 JobTimer를 통한 일감 처리가 마무리 된다. Logn의 복잡도를 가진 우선 순위 큐를 진행하기에 빠른 탐색도 가능하고, 현재 가능한 부분만 체크하면서 진행하기에 훨씬 효율적으로 동작이 된다.

패킷을 만들고 보내는 것 부터 더 효율적으로 패킷을 보내고 처리하는 과정을 배웠다.

아직 익숙하지 않아 더 반복은 필요하지만 좋은 강의 덕분에 어려운 개념을 이해할 수 있어 좋았다.

이제 유니티에 적용해보는 예제만 남았다. 컴퓨터가 많이 안 좋아서 추후에 진행할 예정이다.

profile
인디 게임을 만들며 공부하고 있습니다.

0개의 댓글