Line의 Armeria에 이어, 근 1달만에 Apache의 SeaTunnel이라는 오픈소스에 기여할 수 있었습니다.
Good First Issue라서 쉬울거라 생각하고 맡았지만, 예상보다는 쉽지 않고 우여곡절도 꽤나 있었습니다 ㅋㅋ
메인테이너와 커미터들이 도와주지 않았다면 쉽지 않았을 여정이라고 생각합니다....!
https://github.com/apache/seatunnel/issues/10681
[Feature][Zeta] Implement proper dry-run mode with progressive validation layers · Issue #10681 · apache/seatunnel
Motivation SeaTunnel currently lacks a meaningful dry-run capability. The existing --check flag (SeaTunnelConfValidateCommand) is effectively a stub — its execute() body contains only a // TODO: va...
github.com
제가 기여한 코드는 위 이슈와 관련이 되어있습니다.
SeaTunnel은 대용량 데이터 모으고, 가공하고, 전송하는(ETL) 를 처리할 수 있는 파이프라인 엔진입니다.
SeaTunnel을 사용하기 위해서는 다음과 같은 설정 파일이 필요합니다.
env {
job.mode = "BATCH"
}
source {
FakeSource {
plugin_output = "fake"
row.num = 100
schema = {
fields {
name = "string"
age = "int"
card = "int"
}
}
}
}
transform {
Filter {
plugin_input = "fake"
plugin_output = "fake1"
fields = [name, card]
}
}
sink {
Clickhouse {
host = "clickhouse:8123"
database = "default"
table = "seatunnel_console"
fields = ["name", "card"]
username = "default"
password = ""
plugin_input = "fake1"
}
}
저는 dry-run 기능을 구현했고, 메인테이너가 제시한 layer 0-3 중 layer0을 우선적으로 구현했습니다.
cli에서 --dry-run=static을 입력하면 자체적으로 정적검사를 수행하는 기능입니다.
컴파일 단계와 비슷한 검증이라고 생각됩니다.
layer0에서는
- syntax
- option key
- required
- type
- plugin load
- DAG(Directed Acyclic Graph)
- SQL parsing
위와 같은 항목들을 정적으로 검증하는 로직을 구현했습니다.
SeaTunnel에서는 OptionRule이라는 기존 로직이 있었기 때문에 제가 검증로직을 0부터 개발하지는 않아도 됐습니다. (굿!)
이 과정에서 배운점이 몇가지 있었는데요,
1. JVM classLoader의 동작과정
막연하게 Java가 어떻게 코드를 실행하는가에 대해서는 알고있었습니다.
SeaTunnel에 기여하면서 ClassLoader의 동작 메커니즘을 조금 더 자세하게 알 수 있었는데요,
package org.apache.seatunnel.core.starter.seatunnel.command;
위 경로에서
Thread.currentThread().getContextClassLoader();
다음과 같은 코드를 호출하면
core 모듈 밖에 있는 plugin의 jar 파일들을 알 수 없기 때문에 실제 사용 시 문제가 발생할 수 있었습니다.
plugin jar 경로를 명시적으로 classloader에 추가하라는 팁을 받았고, 이를 구현하며 문제를 잘 해결할 수 있었습니다.
2. 테스트 코드의 중요성
오픈소스 기여할 때 마다 느끼고 있는 부분입니다.
AI로 인해 생산성이 많이 올라간 것을 다들 아실거라고 생각합니다.
저는 아직까지는 코드에 대해 안정성을 확보하기 위해선 잘 작성된 테스트 코드가 필수적이라고 생각합니다.
@Test
public void testInvalidDagTopology() {
ClientCommandArgs args = buildArgs("config/invalid_dag_topology.json");
SeaTunnelConfValidateCommand command = new SeaTunnelConfValidateCommand(args);
ConfigCheckException exception =
Assertions.assertThrows(ConfigCheckException.class, command::execute);
Assertions.assertTrue(
exception.getMessage().contains("Miss <Sink> config"),
"Should detect invalid DAG. Actual: " + exception.getMessage());
}
위와 같은 테스트 코드를 작성했었는데요, 잘 돌아가던 CI에서 어느 순간 테스트가 깨져서 디버깅을 해봤습니다.
이유는 다른 PR에서 설정파일을 암호화, 복호화 하는 코드뿐만 아니라 설정 파일을 검증하는 코드도 try/catch문으로 감싸 설정파일 예외도 "Failed to decrypt config"와 같은 보안 관련 에러 메세지를 던져서 발생하는 문제였습니다.
문제가 발생한 코드의 구조를 수정해서 사용자에게 정확한 에러메세지를 제공할 수 있도록 했습니다.
테스트 코드의 역할은 의도하지 않은 사이드 이펙트를 잡아내는 것 뿐만 아니라
내가 작성한 코드의 안정성과 거대한 프로젝트에서의 협업에도 도움이 된다는 것을 다시 한 번 느끼게 되었습니다.
https://github.com/apache/seatunnel/pull/10763
[Feature][Zeta] Implement proper dry-run mode with progressive validation layer0 by junjunclub · Pull Request #10763 · apache/
Purpose of this pull request This pull request implements Layer 0 (Static Analysis) for the --dry-run feature, addressing the core requirements discussed in #10681. It enhances SeaTunnelConfValidat...
github.com
제가 올린 PR 링크입니다.
기회가 된다면 남은 layer 1, 2, 3도 구현해보고 싶다는 욕심이 듭니다 ㅎㅎ
긴 글 읽어주셔서 감사합니다!
'오픈소스' 카테고리의 다른 글
| line / armeria 오픈소스 기여후기 (open source contribute) (0) | 2026.04.03 |
|---|