포스트

2023-10-23-TIL

2023-10-23-TIL

Today I Studied

Feature Flagging(Toggle)

피처 플래그(피처 토글)는 코드를 배포하는 일과 기능을 사용자에게 여는 일을 분리하는 기법이다. 새 기능 코드를 조건문 뒤에 두고 배포한 다음, 설정이나 관리 화면에서 플래그를 켜고 끄며 기능 노출을 정한다. 문제가 생기면 롤백 배포 없이 플래그만 꺼서 되돌릴 수 있다.

Martin Fowler 사이트의 Feature Toggles 글은 토글을 목적에 따라 네 종류로 나눈다.

종류목적수명
Release Toggle미완성 기능을 꺼 둔 채 트렁크에 합치고 배포짧음(글은 1~2주 이상 두지 말라고 권함)
Experiment Toggle사용자 집단별로 다른 코드 경로를 태워 A/B 테스트통계적으로 의미 있는 결과가 나올 때까지
Ops Toggle성능 영향이 불확실한 기능을 운영 중에 빠르게 끄거나 낮춤짧은 것부터 상시 유지되는 것까지
Permissioning Toggle특정 사용자(내부 직원, 유료 사용자 등)에게만 기능 노출긺

같은 글은 토글을 유지 비용이 드는 재고로 보라고 한다. 플래그가 늘어날수록 조합해야 할 코드 경로와 테스트가 늘어나므로, 역할을 다한 토글은 적극적으로 지워야 한다. LaunchDarkly나 Unleash 같은 도구는 플래그를 코드 밖에서 관리하고 사용자 속성에 따라 대상을 나누는 기능을 제공한다.

  • https://launchdarkly.com/blog/what-are-feature-flags/
  • https://velog.io/@kshired/DevOps-Feature-flag%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C
  • https://www.optimizely.com/optimization-glossary/feature-flags/
  • https://www.atlassian.com/solutions/devops/integrations/feature-flags
  • https://martinfowler.com/articles/feature-toggles.html
  • https://en.wikipedia.org/wiki/Feature_toggle
  • https://sungjk.github.io/2023/03/04/feature-toggle.html
  • https://www.getunleash.io/blog/feature-toggle-best-practices
  • https://medium.com/trueengineering/how-feature-flags-help-build-a-software-factory-65b38ef92f15

Today I Learned

File Download API

DB 데이터를 가공해 큰 파일로 내려주는 API를 단순하게 만들면, 파일을 다 만들 때까지 응답이 없어 게이트웨이 타임아웃(504)이 나거나 서버 메모리가 부족해진다. dev.to의 대용량 다운로드 설계 글은 세 가지 방식을 비교한다.

  1. 큐와 워커를 쓰는 비동기 방식: 요청을 큐에 넣고 워커가 파일을 만들어 S3에 올린 뒤 pre-signed URL을 돌려준다. 클라이언트는 완료될 때까지 상태를 폴링한다. 확장성은 좋지만 사용자 경험과 인프라 비용이 단점이다.
  2. 웹소켓 기반 이벤트 방식: 폴링 대신 완료 이벤트를 웹소켓으로 알린다.
  3. API에서 스트리밍: 데이터를 조금씩 읽고 변환해 바로 응답으로 흘려보낸다. 글은 이 방식을 결론으로 권한다.

Spring에서 스트리밍 방식을 구현하려면 응답 전체를 메모리에 올리지 않고 StreamingResponseBody 등으로 출력 스트림에 바로 쓴다. 다운로드 응답에는 Content-Disposition: attachment; filename=... 헤더를 붙여 브라우저가 파일로 저장하게 한다.

  • https://dev.to/sridharcr/design-architecture-for-large-file-downloads-1ojn
  • https://medium.com/analytics-vidhya/strive-to-upload-or-download-files-using-spring-boot-964336b3ddc7
  • https://docs.oracle.com/en/cloud/paas/content-cloud/rest-api-documents/op-documents-api-1.2-files-fileid-data-get.html

Lombok @Getter to Allow Optional Return

null일 수 있는 필드의 getter가 Optional을 돌려주게 Lombok으로 자동 생성할 수 있을까? 지금은 그런 옵션이 없다. Lombok 이슈 #1957이 2018년에 바로 이 기능, 예를 들어 @Getter(optional = true) 같은 옵션을 요청했다. 이슈 작성자는 필드 타입 자체를 Optional로 바꾸는 것은 좋지 않다고 본다. setter도 Optional을 받게 되고, Optional을 필드로 쓰는 것은 IDE도 경고하는 관행이기 때문이다.

반대쪽 시각은 wheejuni 블로그가 정리한다. 글은 Stack Overflow 답변을 인용해 Optional이 모든 null을 대체하려는 범용 타입이 아니라 라이브러리 메서드 반환 타입에 “결과 없음”을 표현하려는 제한된 수단이었다고 설명한다. 그래서 getter마다 Optional을 돌려주는 것은 과용이라고 본다. 필요한 경우에는 Lombok 대신 Optional.ofNullable(field)를 반환하는 메서드를 직접 작성하면 된다.

  • https://github.com/projectlombok/lombok/issues/1957
  • https://medium.com/@johnpang/optionals-and-lombok-a414639dca1e
  • https://tech.wheejuni.com/2017/12/03/why-no-optional-for-getters/

Lombok @Getter with Default Value

필드 초기값을 Lombok @Builder와 함께 쓰면 함정이 있다. 필드에 private List<String> tags = new ArrayList<>();처럼 초기값을 써 두어도 빌더로 만든 객체에는 그 값이 들어가지 않는다. 빌더가 필드 초기화 코드를 거치지 않고 생성자에 직접 값을 넘기기 때문이다. 초기값을 빌더에도 적용하려면 필드에 @Builder.Default를 붙인다.

Baeldung 글에 따르면 Lombok 1.18.2 이전에는 @Builder.Default를 붙이면 반대로 인자 없는 생성자로 만든 객체에 초기값이 들어가지 않는 문제가 있었다. 글은 초기값을 두 군데에 중복해서 쓰는 대신 toBuilder()로 기본 객체에서 빌더를 만드는 방법도 소개한다.

  • https://www.baeldung.com/lombok-builder-default-value
이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다