Task.Supervisor — 태스크용 슈퍼바이저
Task.Supervisor — 태스크용 슈퍼바이저
동시에 여러 태스크를 안전하게 감독하면서 실행하고 싶을 때 쓰는 것이 Task.Supervisor예요. 이 모듈은 태스크를 동적으로 감독하는 데 사용할 수 있는 슈퍼바이저를 정의해요.
본문
태스크 슈퍼바이저는 자식이 없는 상태로 시작되며, 보통 다른 슈퍼바이저 아래에 이름을 붙여서 시작해요.
children = [
{Task.Supervisor, name: MyApp.TaskSupervisor}
]
Supervisor.start_link(children, strategy: :one_for_one)
자식 스펙에 주는 옵션들은 start_link/1에 문서화되어 있어요. 일단 시작되면 슈퍼바이저 아래에서 태스크를 직접 시작할 수 있어요.
task = Task.Supervisor.async(MyApp.TaskSupervisor, fn ->
:do_some_work
end)
더 자세한 예시는 Task 모듈 문서를 참고하면 돼요.
확장성과 파티셔닝(Scalability and partitioning)
Task.Supervisor는 다른 프로세스를 시작하는 단일 프로세스예요. 어떤 애플리케이션에서는 이 슈퍼바이저가 병목(bottleneck) 이 될 수 있어요. 이를 해결하려면 Task.Supervisor 인스턴스를 여러 개 시작하고, 태스크를 시작할 인스턴스를 무작위로 고르면 돼요.
PartitionSupervisor를 쓰면 코어마다 동적 슈퍼바이저를 기본으로 하나씩 시작하게 만들 수 있어요.
children = [
{PartitionSupervisor,
child_spec: Task.Supervisor,
name: MyApp.TaskSupervisors}
]
그 다음에는 이름 대신 파티션 슈퍼바이저를 통해 {:via, PartitionSupervisor, {name, key}} 형식으로 태스크를 시작해요. 여기서 name은 파티션 슈퍼바이저 이름, key는 라우팅 키예요.
Task.Supervisor.async(
{:via, PartitionSupervisor, {MyApp.TaskSupervisors, self()}},
fn -> :do_some_work end
)
위 코드에서 라우팅 키로 self()를 골랐는데, 이는 각 프로세스가 기존 태스크 슈퍼바이저 중 하나에 할당된다는 뜻이에요. 더 자세한 내용은 PartitionSupervisor 문서를 보면 돼요.
이름 등록(Name registration)
Task.Supervisor는 GenServer와 같은 이름 등록 규칙을 따르므로, GenServer 문서의 이름 등록 부분을 참고하면 돼요.
더 알아보기
- 시작:
Task.Supervisor.start_link/1,Task.Supervisor.start_child/2 - 동시 실행:
Task.Supervisor.async/2,Task.Supervisor.async_nolink/2 - 가시성·관리:
Task.Supervisor.count_children/1,Task.Supervisor.which_children/1,Task.Supervisor.terminate_child/2 - 관련 모듈:
Task,PartitionSupervisor,Supervisor - 가이드:
task-and-gen-tcp