8.이벤트 루프
이벤트 루프란 서버에서 발생한 네트워크 이벤트를 처리하기 위해 동작하는 무한 루프 스레드를 의미함
채널에서 발생한 이벤트는 이벤트 큐에 입력되고,
이벤트 루프는 이벤트 큐에 입력된 이벤트가 있을 때 해당 이벤트를 꺼내서 이벤트를 실행하는데,
이것이 이벤트 루프의 기본 개념이라고 볼 수 있음
네티가 이벤트를 처리하기 위해 내부적으로 사용하는 API는 SingleThreadEventExecutor로, 해당 클래스의 핵심 코드는 다음과 같음
SingleThreadEventExecutor.java
package io.netty.util.concurrent;
// import ...
public abstract class SingleThreadEventExecutor extends AbstractScheduledEventExecutor implements OrderedEventExecutor {
// ...
// 채널에서 발생한 이벤트를 저장할 이벤트 큐 선언,
// Netty는 이벤트를 task라는 이름으로 선언하여 처리함
private final Queue<Runnable> taskQueue;
// ...
// LinkedBlockingQueue로 taskQueue 객체 생성
protected Queue<Runnable> newTaskQueue(int maxPendingTasks) {
return new LinkedBlockingQueue(maxPendingTasks);
}
// taskQueue에 적재된 이벤트를 하나 가져옴
protected Runnable pollTask() {
assert this.inEventLoop();
return pollTaskFrom(this.taskQueue);
}
// pollTask()가 내부적으로 호출하는 메서드, task가 WAKEUP_TASK일 경우, taskQueue에서 이벤트를 하나 꺼냄
protected static Runnable pollTaskFrom(Queue<Runnable> taskQueue) {
Runnable task;
do {
task = (Runnable)taskQueue.poll();
} while(task == WAKEUP_TASK);
return task;
}
// taskQueue에서 꺼낸 이벤트(task)를 수행하는 메서드
protected final boolean runAllTasksFrom(Queue<Runnable> taskQueue) {
Runnable task = pollTaskFrom(taskQueue);
if (task == null) {
return false;
} else {
do {
safeExecute(task); // AbstractEventExecutor.safeExecute(Runnable task); 에서 runTask(task);를 통해 작업 수행(task.run()이 호출됨)
task = pollTaskFrom(taskQueue);
} while(task != null);
return true;
}
}
}Last updated on