NEW
폐쇄망에서 Gradle 프로젝트 빌드하기(offline mode)
폐쇄망... 이것도 k-culture 같은거 아닐까요?한국에서는 매우 당연히 여기는 개발 방식? 환경? 문화? 중에 하나가 바로 폐쇄망입니다.저도 회사생활을 처음 시작했을때 주어진 미션이 바로 이거였습니다.요즘엔 프로젝트 설정이나 CI/CD가 오픈소스로 많이 보급되고 통합되면서 이런 자잘한 DevOps관련 세팅이 쉬워졌지만Spring Boot가 나오기 전인 2014년 전까지는 다른 컴퓨터에서 프로젝트가 정상적으로 빌드가 되게 하는것도 일이었습니다.Spring MVC로 백엔드 개발 커리어를 시작하신분들이라면 많이 공감하실겁니다 ㅎㅎ...암튼 한국 회사에서 개발자(또는 엔지니어)로 일을 한다면 폐쇄망을 한번쯤 겪어보실텐데요.그러다보니 보통 처음 겪는 문제가 바로 폐쇄망 환경에서 프로젝트를 세팅하는것입니다.내 PC에서 다 개발했는데 폐쇄망에 있는 서버에 배포해야되는거죠.보통 대기업이나 금융권(은행,증권사) 또는 규모가 큰 서비스를 운영하는 기업들은 "ISMS"라고 하는 "정보보호 관리체계 인증"을 받습니다.하는 궁극적인 이유는 바로 기업이 고객의 개인정보를 잘 보호하라고 법적으로 의무화한거죠.해당 제도는 2001년에 시행되었고2010년에 "PIMS"라고 하는 "개인정보보호 관리체계 인증"이 시행되고2013년에 추가적으로 "PIPL"라는 "개인정보보호 인증"이 나왔다가2016년에 PIMS, PIPL인증이 하나로 통합되고2018년에 최종적으로 ISMS-P(ISMS+PIMS+PIPL)으로 통합되었습니다.그래서 지금은 ISMS와 ISMS-P 제도 2개만 남았습니다.일반적으로 자율적으로 인증하지만어느정도 기업(서비스)의 규모가 커진다면 의무적으로 인증해야됩니다.그런데 ISMS인증에서 거진 필수조건 중 하나가 바로 "망분리"입니다.네트워크(망)을 물리적(ex - PC) 또는 논리적(ex - VDI)으로 분리하는게 바로 망분리입니다.망분리를 하는 이유는 ISMS인증 기준 중 "2.6.7. 인터넷 접속 통제" 때문입니다.인터넷을 통한 정보 유출, 악성코드 감염, 내부망 침투 등을 예방하기 위하여주요 정보시스템, 주요 직무 수행 및 개인정보 취급 단말기 등에 대한 인터넷 접속 또는 서비스(P2P, 웹하드, 메신저 등)를 제한하는 등 인터넷 접속 통제 정책을 수립·이행하여야 한다.즉, 인터넷으로 중요한 데이터가 유출될 수 있으니 인터넷 접근을 통제해야된다는 겁니다.보통 서버가 직접 해킹 당하기보단 업무용PC가 해킹 당하면서 서버까지 propagation(전파)되는 경우가 많은데애초에 인터넷을 차단하면 해킹당해도 인터넷이 안되니깐 데이터를 빼갈 수 없게하는거죠.그래서 이 기준을 충족하기 위해서 사무용PC, 개발용PC, 서버를 물리적으로 분리(각각 별도 PC로 사용)해서 쓰기도 하고사무용PC를 지급하고 VDI라고 하는 가상 데스크톱으로 개발용PC를 대체하기도 합니다.그래서 보통은 사무용PC에서 개발용VDI를 접속해서 서버로 접근합니다.좀 보안을 더 강화한 경우에는사무용PC에서 사무용VDI를 통해 개발용VDI를 통해 상용VDI를 통해서 상용서버(production)
java
spring
1/8/2025
폐쇄망에서 Gradle 프로젝트 빌드하기(offline mode)
NEW
폐쇄망... 이것도 k-culture 같은거 아닐까요?한국에서는 매우 당연히 여기는 개발 방식? 환경? 문화? 중에 하나가 바로 폐쇄망입니다.저도 회사생활을 처음 시작했을때 주어진 미션이 바로 이거였습니다.요즘엔 프로젝트 설정이나 CI/CD가 오픈소스로 많이 보급되고 통합되면서 이런 자잘한 DevOps관련 세팅이 쉬워졌지만Spring Boot가 나오기 전인 2014년 전까지는 다른 컴퓨터에서 프로젝트가 정상적으로 빌드가 되게 하는것도 일이었습니다.Spring MVC로 백엔드 개발 커리어를 시작하신분들이라면 많이 공감하실겁니다 ㅎㅎ...암튼 한국 회사에서 개발자(또는 엔지니어)로 일을 한다면 폐쇄망을 한번쯤 겪어보실텐데요.그러다보니 보통 처음 겪는 문제가 바로 폐쇄망 환경에서 프로젝트를 세팅하는것입니다.내 PC에서 다 개발했는데 폐쇄망에 있는 서버에 배포해야되는거죠.보통 대기업이나 금융권(은행,증권사) 또는 규모가 큰 서비스를 운영하는 기업들은 "ISMS"라고 하는 "정보보호 관리체계 인증"을 받습니다.하는 궁극적인 이유는 바로 기업이 고객의 개인정보를 잘 보호하라고 법적으로 의무화한거죠.해당 제도는 2001년에 시행되었고2010년에 "PIMS"라고 하는 "개인정보보호 관리체계 인증"이 시행되고2013년에 추가적으로 "PIPL"라는 "개인정보보호 인증"이 나왔다가2016년에 PIMS, PIPL인증이 하나로 통합되고2018년에 최종적으로 ISMS-P(ISMS+PIMS+PIPL)으로 통합되었습니다.그래서 지금은 ISMS와 ISMS-P 제도 2개만 남았습니다.일반적으로 자율적으로 인증하지만어느정도 기업(서비스)의 규모가 커진다면 의무적으로 인증해야됩니다.그런데 ISMS인증에서 거진 필수조건 중 하나가 바로 "망분리"입니다.네트워크(망)을 물리적(ex - PC) 또는 논리적(ex - VDI)으로 분리하는게 바로 망분리입니다.망분리를 하는 이유는 ISMS인증 기준 중 "2.6.7. 인터넷 접속 통제" 때문입니다.인터넷을 통한 정보 유출, 악성코드 감염, 내부망 침투 등을 예방하기 위하여주요 정보시스템, 주요 직무 수행 및 개인정보 취급 단말기 등에 대한 인터넷 접속 또는 서비스(P2P, 웹하드, 메신저 등)를 제한하는 등 인터넷 접속 통제 정책을 수립·이행하여야 한다.즉, 인터넷으로 중요한 데이터가 유출될 수 있으니 인터넷 접근을 통제해야된다는 겁니다.보통 서버가 직접 해킹 당하기보단 업무용PC가 해킹 당하면서 서버까지 propagation(전파)되는 경우가 많은데애초에 인터넷을 차단하면 해킹당해도 인터넷이 안되니깐 데이터를 빼갈 수 없게하는거죠.그래서 이 기준을 충족하기 위해서 사무용PC, 개발용PC, 서버를 물리적으로 분리(각각 별도 PC로 사용)해서 쓰기도 하고사무용PC를 지급하고 VDI라고 하는 가상 데스크톱으로 개발용PC를 대체하기도 합니다.그래서 보통은 사무용PC에서 개발용VDI를 접속해서 서버로 접근합니다.좀 보안을 더 강화한 경우에는사무용PC에서 사무용VDI를 통해 개발용VDI를 통해 상용VDI를 통해서 상용서버(production)
2025.01.08
java
spring
좋아요
별로에요
NEW
FE News 25년 1월 소식을 전해드립니다!
주요내용25년 1월 소식에서는 다음과 같은 유용한 정보들을 만나보실 수 있습니다.Web Almanac 2024전 세계 1천7백만개의 웹사이트를 분석, 현재 웹 기술의 사용과 웹페이지들의 상태를 확인할 수 있습니다.JavaScript Benchmarking Is a MessJS 벤치마크 수행결과는 얼만큼 신뢰할 수 있을까요? 어떤 요소들이 결과에 영향을 미치고 있을까요?How Big Technical Changes Happen at SlackSlack은 기술적 변화를 어떻게 관리하고 기술 도입을 위한 전략을 확인해 보세요.Anders Hejlsberg: How we wrote the TypeScript compilerTS 코어 개발자로부터 들어보는 TS 컴파일러 개발 이야기>> FE News 25년 1월 소식 보러가기 ◎ FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다.매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다.▷ 구독하기
1/8/2025
FE News 25년 1월 소식을 전해드립니다!
NEW
주요내용25년 1월 소식에서는 다음과 같은 유용한 정보들을 만나보실 수 있습니다.Web Almanac 2024전 세계 1천7백만개의 웹사이트를 분석, 현재 웹 기술의 사용과 웹페이지들의 상태를 확인할 수 있습니다.JavaScript Benchmarking Is a MessJS 벤치마크 수행결과는 얼만큼 신뢰할 수 있을까요? 어떤 요소들이 결과에 영향을 미치고 있을까요?How Big Technical Changes Happen at SlackSlack은 기술적 변화를 어떻게 관리하고 기술 도입을 위한 전략을 확인해 보세요.Anders Hejlsberg: How we wrote the TypeScript compilerTS 코어 개발자로부터 들어보는 TS 컴파일러 개발 이야기>> FE News 25년 1월 소식 보러가기 ◎ FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다.매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다.▷ 구독하기
2025.01.08
좋아요
별로에요
토스증권 Apache Kafka 데이터센터 이중화 구성 #1
안녕하세요. 토스증권 실시간 데이터팀 강병수 입니다. 토스증권은 데이터센터 장애 상황에도 유저에게 정상적으로 서비스를 제공하기 위해 대부분의 시스템을 이중화했습니다.Kafka 이중화에 대해서는 2023년 6월 토스 개발자 컨퍼런스 SLASH23에서 한 차례 발표한 바 있는데요. 이번 아티클에서는 3부작으로 구성해 보다 상세하게 설명드리려고 합니다.본 글인 1부에서는 Kafka 이중화 구성에 대한 개요를 담았습니다. 2부에서는 토스증권에서 채택한 Active-Active 구성에서 중요한 부분인 양방향 데이터 미러링에 대해 소개하고, 3부에서는 Active-Active 구성을 채택 했을 때 운영적으로 높은 난이도를 요구하는 양방향 Consumer Group Offset Sync에 대해 설명하는 순서로 이어집니다.Kafka 이중화의 필요성Kafka 이중화에 대한 고민과 설계는 데이터센터 장애 상황에도 정상적으로 서비스를 동작시키기 위해 시작됐습니다. 한쪽 데이터센터에 장애가 발생하여 동작하지 않는 상황에도 서비스를 제공할 수 있으려면 어떻게 해야 할까요?답은 간단합니다. 다른 지역의 데이터센터에 서비스 서버를 소산해놓고 정상 동작하는 데이터센터로 유저 트래픽을 모두 몰아주면 됩니다.토스증권의 서비스 서버 구성은 아래와 같은 특성을 갖고 있습니다.• None 서버를 운영하는 Kubernetes는 두 곳의 데이터센터에 비슷한 스팩으로 구성돼있습니다.• None 두 데이터센터 모두 평시에 유저 트래픽을 처리하는 Active-Active 구성입니다.• None 서버는 MSA 구조로 설계되어 Kafka를 메시지 브로커로 활용합니다.서비스 서버는 Active-Active로 구성돼 이중화 됐습니다. 하지만 MSA에서 메시지 브로커 역할을 하는 Kafka가 이중화 돼있지 않으면 실제 데이터센터 장애 상황 발생 시 서비스는 정상 동작하지 않을 것이 분명합니다. Kafka 역시 데이터센터 이중화를 해야 하는 상황이 됐습니다.서비스 서버가 stateless하게 구현됐다면 상대적으로 이중화 구성이 간단합니다. 하지만 stateless한 서비스 서버와 다르게 stateful한 Kafka는 이중화 구성에 더 많은 고민이 필요합니다. 어떻게 구성해야 좋은 아키텍처가 될까요?Kafka 이중화 구성은 크게 두 가지 아키텍처가 있습니다. Active-Active 구성과 Stretched Cluster 구성입니다. 이해를 돕기 위해 그림으로 먼저 볼게요.• None 그림 2. Active-Active 구성은 서로 독립적인 Kafka 클러스터를 양쪽 데이터센터에 각각 구성하는 방식입니다. 독립된 두 Kafka 클러스터를 동기화해주기 위해 양방향 데이터 미러링이 필요합니다.• None 그림 3. Stretched Cluster 구성은 양쪽 데이터센터에 분리된 노드를 하나의 Kafka 클러스터로 묶어서 구성합니다. 물리적으로 분리돼있지만, 한 개의 Kafka 클러스터라 별도 데이터 미러링 작업이 필요 없이 동기화 됩니다.두 구성 모두 데이터센터 장애 상황에 가용성을 확보할 수 있다
kafka
1/7/2025
토스증권 Apache Kafka 데이터센터 이중화 구성 #1
안녕하세요. 토스증권 실시간 데이터팀 강병수 입니다. 토스증권은 데이터센터 장애 상황에도 유저에게 정상적으로 서비스를 제공하기 위해 대부분의 시스템을 이중화했습니다.Kafka 이중화에 대해서는 2023년 6월 토스 개발자 컨퍼런스 SLASH23에서 한 차례 발표한 바 있는데요. 이번 아티클에서는 3부작으로 구성해 보다 상세하게 설명드리려고 합니다.본 글인 1부에서는 Kafka 이중화 구성에 대한 개요를 담았습니다. 2부에서는 토스증권에서 채택한 Active-Active 구성에서 중요한 부분인 양방향 데이터 미러링에 대해 소개하고, 3부에서는 Active-Active 구성을 채택 했을 때 운영적으로 높은 난이도를 요구하는 양방향 Consumer Group Offset Sync에 대해 설명하는 순서로 이어집니다.Kafka 이중화의 필요성Kafka 이중화에 대한 고민과 설계는 데이터센터 장애 상황에도 정상적으로 서비스를 동작시키기 위해 시작됐습니다. 한쪽 데이터센터에 장애가 발생하여 동작하지 않는 상황에도 서비스를 제공할 수 있으려면 어떻게 해야 할까요?답은 간단합니다. 다른 지역의 데이터센터에 서비스 서버를 소산해놓고 정상 동작하는 데이터센터로 유저 트래픽을 모두 몰아주면 됩니다.토스증권의 서비스 서버 구성은 아래와 같은 특성을 갖고 있습니다.• None 서버를 운영하는 Kubernetes는 두 곳의 데이터센터에 비슷한 스팩으로 구성돼있습니다.• None 두 데이터센터 모두 평시에 유저 트래픽을 처리하는 Active-Active 구성입니다.• None 서버는 MSA 구조로 설계되어 Kafka를 메시지 브로커로 활용합니다.서비스 서버는 Active-Active로 구성돼 이중화 됐습니다. 하지만 MSA에서 메시지 브로커 역할을 하는 Kafka가 이중화 돼있지 않으면 실제 데이터센터 장애 상황 발생 시 서비스는 정상 동작하지 않을 것이 분명합니다. Kafka 역시 데이터센터 이중화를 해야 하는 상황이 됐습니다.서비스 서버가 stateless하게 구현됐다면 상대적으로 이중화 구성이 간단합니다. 하지만 stateless한 서비스 서버와 다르게 stateful한 Kafka는 이중화 구성에 더 많은 고민이 필요합니다. 어떻게 구성해야 좋은 아키텍처가 될까요?Kafka 이중화 구성은 크게 두 가지 아키텍처가 있습니다. Active-Active 구성과 Stretched Cluster 구성입니다. 이해를 돕기 위해 그림으로 먼저 볼게요.• None 그림 2. Active-Active 구성은 서로 독립적인 Kafka 클러스터를 양쪽 데이터센터에 각각 구성하는 방식입니다. 독립된 두 Kafka 클러스터를 동기화해주기 위해 양방향 데이터 미러링이 필요합니다.• None 그림 3. Stretched Cluster 구성은 양쪽 데이터센터에 분리된 노드를 하나의 Kafka 클러스터로 묶어서 구성합니다. 물리적으로 분리돼있지만, 한 개의 Kafka 클러스터라 별도 데이터 미러링 작업이 필요 없이 동기화 됩니다.두 구성 모두 데이터센터 장애 상황에 가용성을 확보할 수 있다
2025.01.07
kafka
좋아요
별로에요
코드 품질 개선 기법 2편: 확인 여부를 확인했나요?
안녕하세요. 커뮤니케이션 앱 LINE의 모바일 클라이언트를 개 발하고 있는 Ishikawa입니다.저희 회사는 높은 개발 생산성을 유지하기 위해 코드 품질 및 개발 문화 개선에 힘쓰고 있습니다. 이를 위해 다양한 노력을 하고 있는데요. 그중 하나가 Review Committee 활동입니다.Review Committee에서는 머지된 코드를 다시 리뷰해 리뷰어와 작성자에게 피드백을 주고, 리뷰하면서 얻은 지식과 인사이트를 Weekly Report라는 이름으로 매주 공유하고 있습니다. 이 Weekly Report 중 일반적으로 널리 적용할 수 있는 주제를 골라 블로그에 코드 품질 개선 기법 시리즈를 연재하고 있습니다.이번에 블로그로 공유할 Weekly Report의 제목은 '확인 여부를 확인했나요?'입니다.확인 여부를 확인했나요?다음 함수는 진행률 표시줄을 표시하는 함수입니다.진행률 표시줄은 0에서 1 사이의 값만 허용하도록 다음과 같이 구현했습니다. 이 중 는 를 사용하는 측의 코드입니다. 또한 와 는 각 수치를 상한과 하한에 맞추기 위한 함수입니다( , 과 같습니다).이 코드의 문제점은 무엇일까요?누군가가 확인할 테니까 괜찮아위 코드는 값이 [0, 1] 범위인지 확인하는 책임의 소재가 명확하지 않다는 문제가 있습니다. 상한값은 를 통해 호출자가 지정하는 반면, 하한값은 를 통해 호출 대상이 지정합니다. 이런 함수는 잘못 사용하기 쉬울 뿐 아니라 사양 및 구현 변경 시 버그가 발생하기도 쉽습니다.기본적으로 함수(또는 메서드) 호출은 '풀 프루프(fool proof)'여야 합니다. 이와 같이 구현하기 위한 두 가지 방법을 소개하겠습니다.첫 번째 방법: 믿을 수 있는 것은 자기 자신뿐첫 번째 방법은 함수의 호출 대상 내에서 확인하는 것입니다. 이 방법은 확인된 혹은 확인되지 않은 상태를 타입 안전(type safe)하게 처리할 수 없는 상황에서 특히 효과적입니다.예를 들어 일반적인 는 변역이 [0, 1]로 제한되지 않기 때문에 인수로 주어진 가 항상 [0, 1] 범위 내에 있다고 보장하기 어려울 것입니다. 인수는 사용자가 직접 입력한 값일 수도 있고, 외부 시스템에서 제공된 값일 수도 있는데요. 대부분의 경우 인수는 신뢰할 수 없다고 생각해야 합니다.다음 구현에서는 [0, 1] 범위를 벗어난 값이 입력되면 각각 0, 1로 처리합니다.호출자에서 범위를 벗어난 값에 대한 오류 처리를 다르게 하고 싶다면 '제대로 처리됐는지 여부'를 반환값으로 알려주는 방법도 있습니다. 다음 코드에서는 범위를 벗어난 인수가 입력된 경우 를 반환합니다.두 번째 방법은 값이 특정 범위에 속한다는 것을 보장하는 타입을 만들어 에 올바른 값만 전달되도록 만드는 것입니다. 의 경우 다음과 같이 '검사 완료'를 나타내는 모델을 만들면 좋을 것입니다.범위를 벗어난 값에 대한 오류 처리를 호출자에서 하고 싶다면 다음과 같이 팩토리 함수를 만들거나 실패 가능한 초기화(failable initializer)를 만드는 것도 좋은 방법입니다.이때 팩토리 함수에서 오류를 나타내는 값은 타입
1/7/2025
코드 품질 개선 기법 2편: 확인 여부를 확인했나요?
안녕하세요. 커뮤니케이션 앱 LINE의 모바일 클라이언트를 개 발하고 있는 Ishikawa입니다.저희 회사는 높은 개발 생산성을 유지하기 위해 코드 품질 및 개발 문화 개선에 힘쓰고 있습니다. 이를 위해 다양한 노력을 하고 있는데요. 그중 하나가 Review Committee 활동입니다.Review Committee에서는 머지된 코드를 다시 리뷰해 리뷰어와 작성자에게 피드백을 주고, 리뷰하면서 얻은 지식과 인사이트를 Weekly Report라는 이름으로 매주 공유하고 있습니다. 이 Weekly Report 중 일반적으로 널리 적용할 수 있는 주제를 골라 블로그에 코드 품질 개선 기법 시리즈를 연재하고 있습니다.이번에 블로그로 공유할 Weekly Report의 제목은 '확인 여부를 확인했나요?'입니다.확인 여부를 확인했나요?다음 함수는 진행률 표시줄을 표시하는 함수입니다.진행률 표시줄은 0에서 1 사이의 값만 허용하도록 다음과 같이 구현했습니다. 이 중 는 를 사용하는 측의 코드입니다. 또한 와 는 각 수치를 상한과 하한에 맞추기 위한 함수입니다( , 과 같습니다).이 코드의 문제점은 무엇일까요?누군가가 확인할 테니까 괜찮아위 코드는 값이 [0, 1] 범위인지 확인하는 책임의 소재가 명확하지 않다는 문제가 있습니다. 상한값은 를 통해 호출자가 지정하는 반면, 하한값은 를 통해 호출 대상이 지정합니다. 이런 함수는 잘못 사용하기 쉬울 뿐 아니라 사양 및 구현 변경 시 버그가 발생하기도 쉽습니다.기본적으로 함수(또는 메서드) 호출은 '풀 프루프(fool proof)'여야 합니다. 이와 같이 구현하기 위한 두 가지 방법을 소개하겠습니다.첫 번째 방법: 믿을 수 있는 것은 자기 자신뿐첫 번째 방법은 함수의 호출 대상 내에서 확인하는 것입니다. 이 방법은 확인된 혹은 확인되지 않은 상태를 타입 안전(type safe)하게 처리할 수 없는 상황에서 특히 효과적입니다.예를 들어 일반적인 는 변역이 [0, 1]로 제한되지 않기 때문에 인수로 주어진 가 항상 [0, 1] 범위 내에 있다고 보장하기 어려울 것입니다. 인수는 사용자가 직접 입력한 값일 수도 있고, 외부 시스템에서 제공된 값일 수도 있는데요. 대부분의 경우 인수는 신뢰할 수 없다고 생각해야 합니다.다음 구현에서는 [0, 1] 범위를 벗어난 값이 입력되면 각각 0, 1로 처리합니다.호출자에서 범위를 벗어난 값에 대한 오류 처리를 다르게 하고 싶다면 '제대로 처리됐는지 여부'를 반환값으로 알려주는 방법도 있습니다. 다음 코드에서는 범위를 벗어난 인수가 입력된 경우 를 반환합니다.두 번째 방법은 값이 특정 범위에 속한다는 것을 보장하는 타입을 만들어 에 올바른 값만 전달되도록 만드는 것입니다. 의 경우 다음과 같이 '검사 완료'를 나타내는 모델을 만들면 좋을 것입니다.범위를 벗어난 값에 대한 오류 처리를 호출자에서 하고 싶다면 다음과 같이 팩토리 함수를 만들거나 실패 가능한 초기화(failable initializer)를 만드는 것도 좋은 방법입니다.이때 팩토리 함수에서 오류를 나타내는 값은 타입
2025.01.07
좋아요
별로에요
Vue.js 환경에서 페이지 이탈 방지 팝업 구현하기
안녕하세요. 에이닷에서 프론트엔드 개발자로 일하고 있는 스카이입니다.오늘은 사용자의 편의성을 위해 이탈 방지 팝업을 서비스에 적용하면서 했던 경험을 정리하여 글로 남깁니다.에이닷 회원 가입 과정에서 사용자가 실수로 페이지를 벗어날 때 입력한 정보가 유실되는 문제가 발견되었습니다.이 문제는 사용자 경험을 저해하는 중요한 이슈로, 이탈 방지 팝업을 통해 해결하고자 했습니다.가끔 사이트에서 아래와 같은 팝업을 마주하게 될때가 있습니다.앞서 보여드린 팝업을 노출 시키는 방법은 매우 간단합니다.beforeunload 이벤트를 추가하면 됩니다. 해당 이벤트는 페이지를 벗어나려고 할때 이벤트가 트리거 됩니다.그런데 이벤트 적용 했을때 다음과 같은 문제점이 있었습니다.페이지에 사용자 제스처(클릭/터치)가 없으면 이벤트는 트리거 되지 않습니다.이전 페이지와 현재 페이지의 도메인 주소가 다를때만 동작합니다.에이닷은 Vue.js 기반의 SPA(Single Page Application)입니다. 라우터를 기반으로 화면이 이동되다보니 상위 도메인 경로가 동일합니다.이럴때는 동작하지 않는 문제가 발견되었습니다.브라우저 고유 confirm만 사용 가능해당 이벤트를 사용하면 오직 각 브라우저에서 제공하는 형태의 confirm이 노출됩니다.이전에는 메세지 내용을 변경할수 있게 제공되었으나 현재는 메세지 내용을 바꿀수가 없습니다.onBeforeRouteLeave 이벤트는 Vue.js에서 사용하는 이벤트로 해당 페이지를 벗어나려고 할때 트리거 됩니다.이벤트 사 다음과 같은 문제점이 있었습니다.SPA 환경에서만 동작당연한 말이지만 라우터를 통하면 페이지 이동의 경우에만 발생합니다.의 발생 조건인 이전 페이와 현재 페이지의 도메인이 다른 경우에는 동작하지 않습니다.이벤트가 이벤트 보다 나은 점은 다음과 같습니다.beforeunload 경우 사용자의 동작이 있어야 이벤트가 트리거 되는 조건이 있었습니다.그러나 onBeforeRouteLeave는 사용자 동작 유무와 무관하게 이벤트가 트리거 됩니다.는 각 브라우저에서 제공하는 confirm만 사용이 가능합니다. 메세지 내용을 수정할수 없습니다.는 문구를 변경할수 있습니다. 또한 async/await 제공하는 confirm UI 만들어서 제공할수도 있습니다.에이닷은 다른 도메인을 통해 이동되는 경우와 라우터를 통해 이동되는 경우 2가지가 혼재 합니다. 그래서 두가지 경우를 모두 커버할수 있도록 구현했습니다.효과적인 이탈 방지 팝업 구현을 위해서는 기술적 제약을 이해하고, 다양한 시나리오를 고려한 유연한 접근이 필요합니다.Vue.js 환경에서는 라우터 이벤트와 브라우저 이벤트를 조합하여 최적의 사용자 경험을 제공할 수 있습니다.두 이벤트가 지원하는 브라우저
vuejs
1/7/2025
Vue.js 환경에서 페이지 이탈 방지 팝업 구현하기
안녕하세요. 에이닷에서 프론트엔드 개발자로 일하고 있는 스카이입니다.오늘은 사용자의 편의성을 위해 이탈 방지 팝업을 서비스에 적용하면서 했던 경험을 정리하여 글로 남깁니다.에이닷 회원 가입 과정에서 사용자가 실수로 페이지를 벗어날 때 입력한 정보가 유실되는 문제가 발견되었습니다.이 문제는 사용자 경험을 저해하는 중요한 이슈로, 이탈 방지 팝업을 통해 해결하고자 했습니다.가끔 사이트에서 아래와 같은 팝업을 마주하게 될때가 있습니다.앞서 보여드린 팝업을 노출 시키는 방법은 매우 간단합니다.beforeunload 이벤트를 추가하면 됩니다. 해당 이벤트는 페이지를 벗어나려고 할때 이벤트가 트리거 됩니다.그런데 이벤트 적용 했을때 다음과 같은 문제점이 있었습니다.페이지에 사용자 제스처(클릭/터치)가 없으면 이벤트는 트리거 되지 않습니다.이전 페이지와 현재 페이지의 도메인 주소가 다를때만 동작합니다.에이닷은 Vue.js 기반의 SPA(Single Page Application)입니다. 라우터를 기반으로 화면이 이동되다보니 상위 도메인 경로가 동일합니다.이럴때는 동작하지 않는 문제가 발견되었습니다.브라우저 고유 confirm만 사용 가능해당 이벤트를 사용하면 오직 각 브라우저에서 제공하는 형태의 confirm이 노출됩니다.이전에는 메세지 내용을 변경할수 있게 제공되었으나 현재는 메세지 내용을 바꿀수가 없습니다.onBeforeRouteLeave 이벤트는 Vue.js에서 사용하는 이벤트로 해당 페이지를 벗어나려고 할때 트리거 됩니다.이벤트 사 다음과 같은 문제점이 있었습니다.SPA 환경에서만 동작당연한 말이지만 라우터를 통하면 페이지 이동의 경우에만 발생합니다.의 발생 조건인 이전 페이와 현재 페이지의 도메인이 다른 경우에는 동작하지 않습니다.이벤트가 이벤트 보다 나은 점은 다음과 같습니다.beforeunload 경우 사용자의 동작이 있어야 이벤트가 트리거 되는 조건이 있었습니다.그러나 onBeforeRouteLeave는 사용자 동작 유무와 무관하게 이벤트가 트리거 됩니다.는 각 브라우저에서 제공하는 confirm만 사용이 가능합니다. 메세지 내용을 수정할수 없습니다.는 문구를 변경할수 있습니다. 또한 async/await 제공하는 confirm UI 만들어서 제공할수도 있습니다.에이닷은 다른 도메인을 통해 이동되는 경우와 라우터를 통해 이동되는 경우 2가지가 혼재 합니다. 그래서 두가지 경우를 모두 커버할수 있도록 구현했습니다.효과적인 이탈 방지 팝업 구현을 위해서는 기술적 제약을 이해하고, 다양한 시나리오를 고려한 유연한 접근이 필요합니다.Vue.js 환경에서는 라우터 이벤트와 브라우저 이벤트를 조합하여 최적의 사용자 경험을 제공할 수 있습니다.두 이벤트가 지원하는 브라우저
2025.01.07
vuejs
좋아요
별로에요
현대자동차그룹 글로벌 차량 가입·개통 시스템 개편하기 (feat. MSA)
안녕하세요. 현대자동차그룹 커넥티드 카 서비스(CCS) 백엔드를 개발하고 있는 김성은 책임입니다.이번 신규 국가에 커넥티드 카 서비스를 전개하며 모놀로식 구조의 가입 개통 시스템을 MSA로 이관하고 개선한 경험을 공유하고자 합니다. 개편 프로젝트를 진행하게 된 배경을 시작으로 기존 시스템이 가지고 있었던 문제점을 기술적으로 어떻게 개선했는지를 중점으로 다뤄보겠습니다.커넥티드 카 서비스(CCS)란?현대자동차그룹은 차량 내 인포테인먼트 시스템과 스마트폰을 활용한 커넥티드 카 서비스를 통해 고객에게 더 편리하고 자유로운 모빌리티 경험을 제공하고 있습니다. 서비스의 주요 기능으로는 원격 제어(시동, 문 잠금/해제, 공조 시스템 등), 실시간 차량 상태 확인, 차량 원격 진단 및 무선 소프트웨어 업데이트(OTA), 그리고 비디오 스트리밍 같은 엔터테인먼트 기능까지 제공합니다.해당 서비스는 현대자동차의 블루링크(Bluelink), 기아의 기아 커넥트(Kia Connect), 제네시스의 마이 제네시스(My Genesis) 앱을 통해 이용할 수 있습니다. 2023년 6월 기준 커넥티드 카 서비스는 전 세계적으로 1,000만 명 이상의 가입자를 확보하며 빠르게 성장해 높은 인기를 얻고 있습니다.개편 배경모놀로식 구조와 MSA 혼재글로벌 CCS는 모놀로식(CCS1.0) 구조로 설계되어 운영되고 있었습니다. MSA 전환 프로젝트를 통해 대부분의 시스템은 MSA(CCS2.0)로 전환되었지만, 가입 개통 시스템은 전환되지 않았고 모놀로식 구조를 유지했습니다. 따라서 CCS2.0에서 CCS1.0 가입 개통 시스템을 통해 서비스를 제공하는 모놀로식과 MSA가 혼재된 구조로 서비스를 제공하고 있었습니다.CCS 구조모놀로식으로부터 가입 개통 시스템 분리 필요성기존 국가에서는 CCS1.0 서비스 이용 차량이 아직 존재했기 때문에 CCS1.0과 CCS2.0 서비스를 모두 제공해야 했습니다. 하지만, 신규 국가는 CCS2.0 지원 차량만 판매될 예정이었기 때문에 더 이상 CCS1.0 서비스를 제공할 필요가 없었습니다. 이에 따라, 가입 개통 시스템을 모놀로식 구조로부터 분리하고 개선하는 프로젝트를 진행하게 되었습니다.신규 국가 CCS 구조기존 시스템 한계가입 개통 시스템 자체적으로도 여러 문제점이 있었습니다. 이전 신규 국가에 서비스를 전개할 때는 기존 코드를 기반으로 개발했기 때문에 시스템의 근본적인 문제를 해결하는데 한계가 있었습니다.기술 부채더 이상 유지 보수 되지 않는 자사 프레임워크로 개발Spring 4.3.22, JAVA 8, Mybatis 기술 사용, 테스트 코드 부재높은 코드 복잡도와 낮은 가독성무분별한 Map, if 문, 체크 예외, try-catch 문 사용클라이언트 요청에 대한 공통 처리가 이뤄지지 않음메소드 길이가 길어 해석하기 어려운 코드 존재비효율적인 형상 관리국가별 특화 로직이 거의 없음에도 국가별로 저장소를 나눠 형상 관리동일한 요구사항에 대해 국가별로 다르게 구현되어 국가 간 코드 차이 증가공통 기능 개발이나 버그 수정 시, 반복 작업 필요높은 데이터베이스 부하동일한 레코드를 중복으로 조회하는 비즈니스 로직 존재변하지 않는 데이터에 대한 캐싱이 이뤄지지 않음개편 과정자사 프레임워크는 더 이상 유지 보수되지 않았기 때문에 보안에 취약했고 다른 최신 버전 라이브러리와 호환성이 떨어졌습니다. 이러한 한계를 극복하기 위해, 이번 프로젝트에서는 자사 프레임워크 대신 SpringBoot 기반으로 시스템을 개편하기로 했습니다.레거시 시스템을 다시 개발하는 일은 적지 않은 리스크를 동반합니다. 기존 시스템과 동일한 기능과 동작을 보장해야 하며, 10년 이상 쌓여온 수많은 정책과 복잡한 비즈니스 로직을 정확히 이해하고 개발하는 과정이 필요했습니다. 그럼에도 불구하고, 기술 부채를 회피하지 않고 개선하는 것이 개발자로서 갖춰야 할 태도라고 생각하기 때문에 과감하게 도전했습니다.아래는 이번 시스템 개편의 주요 과정입니다.1. 가입 개통 시스템 비즈니스 로직 파악비즈니스 로직을 파악하기 위한 지름길은 없습니다. 레거시 코드를 하나하나 분석하며 로직을 이해하였고 궁금한 사항은 사내 위키를 참고하거나, 개발에 참여한 PM 또는 개발자분께 직접 물어보며 파악하였습니다.2. 섀도잉 기법을 기반으로 설계 및 개발기존 코드를 기반으로 개발하는 것이 아닌 새롭게 개발했기 때문에 기존 시스템과 동일하게 동작하는지 파악해야 했습니다. 따라서, 레거시 시스템 API 응답 값과 개편 시스템 API 응답 값을 비교하는 섀도잉 기법을 통해 기존 시스템과 동일하게 동작하는지 확인하며 개발하였습니다.3. 개편 시스템 검증개편한 시스템을 검증하기 위해 많은 테스트 코드를 작성하였지만, 이것만으론 신뢰를 얻긴 어려웠습니다. 이를 보완하기 위해 10회 이상의 차량 단말 테스트를 거쳐 시스템의 신뢰성을 확보했습니다.주요 개편 사항유연하고 확장성 높은 시스템 설계가입 개통 시스템 요구사항은 국가 간 대부분 비슷했지만, 약간의 차이가 있어 국가별로 별도의 코드 저장소에 관리되고 각기 다른 개발자가 맡아 운영해 왔습니다. 이로 인해 동일한 요구사항이 국가마다 다르게 구현되면서 코드의 일관성이 떨어지고 시스템 운영 비용이 증가하는 문제가 있었습니다.위 문제를 해결하기 위해 공통 요구사항은 통일된 로직으로 개발하여 코드 일관성을 높이고 전략 패턴과 의존성 주입(DI)을 통해 국가별 특화 로직이 유연하게 적용될 수 있도록 설계하였습니다. 이렇게 시스템의 확장성을 높여 여러 국가가 하나의 프로젝트로 관리될 수 있게 함으로써 시스템 운영 비용을 줄였습니다.레거시 코드 리팩토링레거시 코드에서는 클라이언트 요청에 대한 공통 관심사가 각 컨트롤러에서 처리되었고 무분별한 체크 예외를 처리하기 위해 try ~ catch 문을 많이 사용했습니다. 또한, 함수 파라미터로 Map을 사용하여 코드 복잡도가 높고 가독성이 떨어지는 문제가 있었습니다.핵심 비즈니스 로직으로부터 공통 관심사 분리위 문제를 해결하기 위해 Interceptor와 AOP를 도입하여 공통 관심사를 분리하였습니다. 예외 처리의 경우 체크 예외 대신 언체크 예외를 사용하고 Controller
java
1/6/2025
현대자동차그룹 글로벌 차량 가입·개통 시스템 개편하기 (feat. MSA)
안녕하세요. 현대자동차그룹 커넥티드 카 서비스(CCS) 백엔드를 개발하고 있는 김성은 책임입니다.이번 신규 국가에 커넥티드 카 서비스를 전개하며 모놀로식 구조의 가입 개통 시스템을 MSA로 이관하고 개선한 경험을 공유하고자 합니다. 개편 프로젝트를 진행하게 된 배경을 시작으로 기존 시스템이 가지고 있었던 문제점을 기술적으로 어떻게 개선했는지를 중점으로 다뤄보겠습니다.커넥티드 카 서비스(CCS)란?현대자동차그룹은 차량 내 인포테인먼트 시스템과 스마트폰을 활용한 커넥티드 카 서비스를 통해 고객에게 더 편리하고 자유로운 모빌리티 경험을 제공하고 있습니다. 서비스의 주요 기능으로는 원격 제어(시동, 문 잠금/해제, 공조 시스템 등), 실시간 차량 상태 확인, 차량 원격 진단 및 무선 소프트웨어 업데이트(OTA), 그리고 비디오 스트리밍 같은 엔터테인먼트 기능까지 제공합니다.해당 서비스는 현대자동차의 블루링크(Bluelink), 기아의 기아 커넥트(Kia Connect), 제네시스의 마이 제네시스(My Genesis) 앱을 통해 이용할 수 있습니다. 2023년 6월 기준 커넥티드 카 서비스는 전 세계적으로 1,000만 명 이상의 가입자를 확보하며 빠르게 성장해 높은 인기를 얻고 있습니다.개편 배경모놀로식 구조와 MSA 혼재글로벌 CCS는 모놀로식(CCS1.0) 구조로 설계되어 운영되고 있었습니다. MSA 전환 프로젝트를 통해 대부분의 시스템은 MSA(CCS2.0)로 전환되었지만, 가입 개통 시스템은 전환되지 않았고 모놀로식 구조를 유지했습니다. 따라서 CCS2.0에서 CCS1.0 가입 개통 시스템을 통해 서비스를 제공하는 모놀로식과 MSA가 혼재된 구조로 서비스를 제공하고 있었습니다.CCS 구조모놀로식으로부터 가입 개통 시스템 분리 필요성기존 국가에서는 CCS1.0 서비스 이용 차량이 아직 존재했기 때문에 CCS1.0과 CCS2.0 서비스를 모두 제공해야 했습니다. 하지만, 신규 국가는 CCS2.0 지원 차량만 판매될 예정이었기 때문에 더 이상 CCS1.0 서비스를 제공할 필요가 없었습니다. 이에 따라, 가입 개통 시스템을 모놀로식 구조로부터 분리하고 개선하는 프로젝트를 진행하게 되었습니다.신규 국가 CCS 구조기존 시스템 한계가입 개통 시스템 자체적으로도 여러 문제점이 있었습니다. 이전 신규 국가에 서비스를 전개할 때는 기존 코드를 기반으로 개발했기 때문에 시스템의 근본적인 문제를 해결하는데 한계가 있었습니다.기술 부채더 이상 유지 보수 되지 않는 자사 프레임워크로 개발Spring 4.3.22, JAVA 8, Mybatis 기술 사용, 테스트 코드 부재높은 코드 복잡도와 낮은 가독성무분별한 Map, if 문, 체크 예외, try-catch 문 사용클라이언트 요청에 대한 공통 처리가 이뤄지지 않음메소드 길이가 길어 해석하기 어려운 코드 존재비효율적인 형상 관리국가별 특화 로직이 거의 없음에도 국가별로 저장소를 나눠 형상 관리동일한 요구사항에 대해 국가별로 다르게 구현되어 국가 간 코드 차이 증가공통 기능 개발이나 버그 수정 시, 반복 작업 필요높은 데이터베이스 부하동일한 레코드를 중복으로 조회하는 비즈니스 로직 존재변하지 않는 데이터에 대한 캐싱이 이뤄지지 않음개편 과정자사 프레임워크는 더 이상 유지 보수되지 않았기 때문에 보안에 취약했고 다른 최신 버전 라이브러리와 호환성이 떨어졌습니다. 이러한 한계를 극복하기 위해, 이번 프로젝트에서는 자사 프레임워크 대신 SpringBoot 기반으로 시스템을 개편하기로 했습니다.레거시 시스템을 다시 개발하는 일은 적지 않은 리스크를 동반합니다. 기존 시스템과 동일한 기능과 동작을 보장해야 하며, 10년 이상 쌓여온 수많은 정책과 복잡한 비즈니스 로직을 정확히 이해하고 개발하는 과정이 필요했습니다. 그럼에도 불구하고, 기술 부채를 회피하지 않고 개선하는 것이 개발자로서 갖춰야 할 태도라고 생각하기 때문에 과감하게 도전했습니다.아래는 이번 시스템 개편의 주요 과정입니다.1. 가입 개통 시스템 비즈니스 로직 파악비즈니스 로직을 파악하기 위한 지름길은 없습니다. 레거시 코드를 하나하나 분석하며 로직을 이해하였고 궁금한 사항은 사내 위키를 참고하거나, 개발에 참여한 PM 또는 개발자분께 직접 물어보며 파악하였습니다.2. 섀도잉 기법을 기반으로 설계 및 개발기존 코드를 기반으로 개발하는 것이 아닌 새롭게 개발했기 때문에 기존 시스템과 동일하게 동작하는지 파악해야 했습니다. 따라서, 레거시 시스템 API 응답 값과 개편 시스템 API 응답 값을 비교하는 섀도잉 기법을 통해 기존 시스템과 동일하게 동작하는지 확인하며 개발하였습니다.3. 개편 시스템 검증개편한 시스템을 검증하기 위해 많은 테스트 코드를 작성하였지만, 이것만으론 신뢰를 얻긴 어려웠습니다. 이를 보완하기 위해 10회 이상의 차량 단말 테스트를 거쳐 시스템의 신뢰성을 확보했습니다.주요 개편 사항유연하고 확장성 높은 시스템 설계가입 개통 시스템 요구사항은 국가 간 대부분 비슷했지만, 약간의 차이가 있어 국가별로 별도의 코드 저장소에 관리되고 각기 다른 개발자가 맡아 운영해 왔습니다. 이로 인해 동일한 요구사항이 국가마다 다르게 구현되면서 코드의 일관성이 떨어지고 시스템 운영 비용이 증가하는 문제가 있었습니다.위 문제를 해결하기 위해 공통 요구사항은 통일된 로직으로 개발하여 코드 일관성을 높이고 전략 패턴과 의존성 주입(DI)을 통해 국가별 특화 로직이 유연하게 적용될 수 있도록 설계하였습니다. 이렇게 시스템의 확장성을 높여 여러 국가가 하나의 프로젝트로 관리될 수 있게 함으로써 시스템 운영 비용을 줄였습니다.레거시 코드 리팩토링레거시 코드에서는 클라이언트 요청에 대한 공통 관심사가 각 컨트롤러에서 처리되었고 무분별한 체크 예외를 처리하기 위해 try ~ catch 문을 많이 사용했습니다. 또한, 함수 파라미터로 Map을 사용하여 코드 복잡도가 높고 가독성이 떨어지는 문제가 있었습니다.핵심 비즈니스 로직으로부터 공통 관심사 분리위 문제를 해결하기 위해 Interceptor와 AOP를 도입하여 공통 관심사를 분리하였습니다. 예외 처리의 경우 체크 예외 대신 언체크 예외를 사용하고 Controller
2025.01.06
java
좋아요
별로에요
코틀린 코루틴 예외 처리, 어떻게 해야 할까?
cdragon.cd 코드를 작성할 때 성공 케이스에 대한 로직만큼이나 실패 케이스에 대한 안전한 예외처리는 필수입니다. 구조화된 동시성을 지원하는 코틀린 코루틴에서는 어떻게 예외를 핸들링할 수 있을까요? 반복적으로 try-catch를 작성하고 있었다면 제이코의 글을 통해 더 유려한 예외처리로 리팩토링 해보세요!greg.ss 코틀린 코루틴의 열렬한 지지자, 제이코가 예외 처리에 대해 소개하는 글입니다. 예제와 함께 올바른 방법을 학습하고 자신의 코드를 점검해 보면 어떨까요?안녕하세요, 카카오페이 크레딧클랜에서 대출 플랫폼을 개발하고 있는 제이코입니다. 여러분은 코틀린 코루틴을 사용할 때, 특정 코루틴에서 발생한 예외가 다른 코루틴에 영향을 미쳐 전체 시스템이 불안정해진 경험이 있으신가요? 코루틴은 비동기 프로그래밍의 복잡성을 줄이고 효율적인 동시성을 제공하는 강력한 도구입니다. 하지만 예외 전파와 취소 과정을 제대로 이해하지 못하고 사용하면 전체 시스템이 불안정해질 위험이 있습니다.이번 글에서는 코루틴을 사용할 때 발생할 수 있는 예외로 인한 취소 문제와 이를 해결하기 위한 다양한 방법들을 소개하려고 합니다. 구조화된 동시성 원칙을 중심으로 예외가 어떻게 전파되고, 그로 인해 다른 코루틴에 어떤 영향을 미치는지 구체적인 예제를 통해 살펴볼게요. 이 글이 코루틴을 처음 접하는 분들뿐만 아니라, 실무에서 코루틴을 활용해 안정적이고 신뢰할 수 있는 시스템 설계를 고민하는 모든 분들에게 도움이 되기를 기대합니다.코루틴은 구조화된 동시성 (Structured Concurrency) 원칙을 따릅니다. 이 원칙에 따라 코루틴의 생명 주기와 실행 흐름은 부모-자식 관계로 체계적으로 관리됩니다. 부모 코루틴은 자식 코루틴의 생명 주기를 책임지며, 모든 자식 코루틴이 완료되어야 부모 코루틴도 완료될 수 있습니다. 구조화된 동시성 원칙은 예외 처리에도 중요한 영향을 미칩니다. 자식 코루틴에서 예외가 발생하면 해당 예외는 부모 코루틴으로 전파됩니다. 이를 통해 오류를 체계적으로 관리할 수 있지만, 부모 코루틴이 예외를 적절히 처리하지 못할 경우 전체 코루틴 계층이 취소될 수 있습니다.예외 전파 및 취소의 기본 원리는 다음과 같습니다.• 예외 발생: 코루틴에서 예외가 발생하면 해당 코루틴과 그 하위 코루틴은 모두 취소됩니다.• 예외 전파: 예외는 부모 코루틴으로 전파되며, 부모 코루틴도 취소됩니다.• 전체 계층 취소: 부모 코루틴이 취소되면 다른 자식 코루틴도 모두 취소됩니다.다음 예제를 통해 코루틴의 예외 전파 및 취소 동작을 살펴보겠습니다.실행 결과를 보면, 코루틴 4에서 발생한 예외로 인해 모든 코루틴이 취소된 것을 확인할 수 있습니다.이제 어떤 과정을 거쳐 전체 코루틴이 취소되었는지 살펴볼게요. 아래 그림은 각 코루틴 간의 부모-자식 관계를 나타냅니다.우선, 코루틴 4의 예외 발생으로 인해 코루틴 4가 취소됩니다.코루틴 4의 취소로 인해, 코루틴 4의 자식인 코루틴 5 역시 취소됩니다.코루틴 4에서 발생한 예외는 코루틴 4의 부모 코루틴인 코루틴 1에게
kotlin
1/6/2025
코틀린 코루틴 예외 처리, 어떻게 해야 할까?
cdragon.cd 코드를 작성할 때 성공 케이스에 대한 로직만큼이나 실패 케이스에 대한 안전한 예외처리는 필수입니다. 구조화된 동시성을 지원하는 코틀린 코루틴에서는 어떻게 예외를 핸들링할 수 있을까요? 반복적으로 try-catch를 작성하고 있었다면 제이코의 글을 통해 더 유려한 예외처리로 리팩토링 해보세요!greg.ss 코틀린 코루틴의 열렬한 지지자, 제이코가 예외 처리에 대해 소개하는 글입니다. 예제와 함께 올바른 방법을 학습하고 자신의 코드를 점검해 보면 어떨까요?안녕하세요, 카카오페이 크레딧클랜에서 대출 플랫폼을 개발하고 있는 제이코입니다. 여러분은 코틀린 코루틴을 사용할 때, 특정 코루틴에서 발생한 예외가 다른 코루틴에 영향을 미쳐 전체 시스템이 불안정해진 경험이 있으신가요? 코루틴은 비동기 프로그래밍의 복잡성을 줄이고 효율적인 동시성을 제공하는 강력한 도구입니다. 하지만 예외 전파와 취소 과정을 제대로 이해하지 못하고 사용하면 전체 시스템이 불안정해질 위험이 있습니다.이번 글에서는 코루틴을 사용할 때 발생할 수 있는 예외로 인한 취소 문제와 이를 해결하기 위한 다양한 방법들을 소개하려고 합니다. 구조화된 동시성 원칙을 중심으로 예외가 어떻게 전파되고, 그로 인해 다른 코루틴에 어떤 영향을 미치는지 구체적인 예제를 통해 살펴볼게요. 이 글이 코루틴을 처음 접하는 분들뿐만 아니라, 실무에서 코루틴을 활용해 안정적이고 신뢰할 수 있는 시스템 설계를 고민하는 모든 분들에게 도움이 되기를 기대합니다.코루틴은 구조화된 동시성 (Structured Concurrency) 원칙을 따릅니다. 이 원칙에 따라 코루틴의 생명 주기와 실행 흐름은 부모-자식 관계로 체계적으로 관리됩니다. 부모 코루틴은 자식 코루틴의 생명 주기를 책임지며, 모든 자식 코루틴이 완료되어야 부모 코루틴도 완료될 수 있습니다. 구조화된 동시성 원칙은 예외 처리에도 중요한 영향을 미칩니다. 자식 코루틴에서 예외가 발생하면 해당 예외는 부모 코루틴으로 전파됩니다. 이를 통해 오류를 체계적으로 관리할 수 있지만, 부모 코루틴이 예외를 적절히 처리하지 못할 경우 전체 코루틴 계층이 취소될 수 있습니다.예외 전파 및 취소의 기본 원리는 다음과 같습니다.• 예외 발생: 코루틴에서 예외가 발생하면 해당 코루틴과 그 하위 코루틴은 모두 취소됩니다.• 예외 전파: 예외는 부모 코루틴으로 전파되며, 부모 코루틴도 취소됩니다.• 전체 계층 취소: 부모 코루틴이 취소되면 다른 자식 코루틴도 모두 취소됩니다.다음 예제를 통해 코루틴의 예외 전파 및 취소 동작을 살펴보겠습니다.실행 결과를 보면, 코루틴 4에서 발생한 예외로 인해 모든 코루틴이 취소된 것을 확인할 수 있습니다.이제 어떤 과정을 거쳐 전체 코루틴이 취소되었는지 살펴볼게요. 아래 그림은 각 코루틴 간의 부모-자식 관계를 나타냅니다.우선, 코루틴 4의 예외 발생으로 인해 코루틴 4가 취소됩니다.코루틴 4의 취소로 인해, 코루틴 4의 자식인 코루틴 5 역시 취소됩니다.코루틴 4에서 발생한 예외는 코루틴 4의 부모 코루틴인 코루틴 1에게
2025.01.06
kotlin
좋아요
별로에요
iOS에서 이벤트 기반 URL 요청이 잘 전송되는지 확인하기 (feat. 광고 트래킹.. 제대로 가고 있나요?)
안녕하세요 지마켓 Mobile Application Team 강수진입니다.오늘은 iOS에서 특정 이벤트에 대한 URL 요청이 정상적으로 이루어졌는지 확인하는 방법에 대해 알아보겠습니다.들어가기 전에모든 서비스에서 광고는 중요합니다. 왜냐하면 수익과 직결되기 때문이죠 지마켓도 곳곳에 다양한 유형의 광고가 포함되어 있는데요! 일례로 사용자가 광고 상품을 클릭하면, 해당 이벤트가 광고 처리 시스템으로 전송되어 광고가 집계되고, 이에 따라 비용이 청구될 수 있습니다.요구 사항광고 트래킹은 수익과 직결되기 때문에 문제가 생기면 최우선 순위로 대응해야 하는 이슈 중 하나입니다.그런데 코드 수정을 하다가 기존의 트래킹 코드가 동작을 안 하는 상황이 발생한다면요..?? 심지어 이런 데이터 트래킹의 이슈는 일반적인 QA로 발견되기 어려운데요...? 벌써 아찔하죠..? 그렇다면 배포 전 테스트를 통해 '광고 트래킹 이벤트가 발생했을때, 해당 URL 요청을 제대로 보내고 있는지' 확인할 수 없을까요??이번 프로젝트는 이러한 필요성으로부터 시작됩니다.어떻게 하면 좋을까?앞서 말했듯 '광고 이벤트가 발생하면, 광고 처리 시스템 URL 로 트래킹을 보낸다' 이것이 광고 시스템 처리에 대한 기본 전제입니다.하지만 트리거 이벤트가 발생했을때 진짜로 광고 URL 요청을 보냈는지 확신할 수 있나요? 정말요?? 이 사실을 어떻게 검증할 수 있을까요?기존에 트래킹 이벤트를 아래와 같이 sendTracking 함수에서 처리한다고 할때protocol AdTracker { func sendTracking()}struct AdTrackingClient: AdTracker { func sendTracking() { // URL Request 보냄 }}단순히 Fake 객체를 만들고, sendTracking 함수에서는 isTrackingSent 플래그를 변경하는 방식으로 트래킹이 되었는지 검증하면 될까요?struct FakeAdTrackingClient: AdTracker { var isTrackingSent = false func sendTracking() { isTrackingSent = true }}이와 같은 방식은 sendTracking 함수가 호출되었는지 여부만 확인할 수 있을 뿐, 실제로 URLRequest를 통해 네트워크 요청이 이루어졌는지는 확인할 수 없습니다. 실제 AdTrackingClientAdTrackingClient의 sendTracking 함수에서는 print("hello world")만 구현되어 있을지도 모르는 일이죠!따라서 저희는 실제 URL 요청을 캐치할 수 있는 proxy 를 만들어서 이벤트를 가로채기로 했습니다. 그리고 여기서 가로챈 URL 정보는 저장소에 별도로 저장해 둡니다.광고 트래킹 이벤트를 트리거 시킬 때 URL 요청을 제대로 보낸다면, 해당 URL 정보는 proxy에 의해 저장소에 저장될 겁니다.그럼 우리는 이벤트 트리거 후 URL 이 저장소에 있냐 / 아니냐에 따라서 이벤트에 따른 URL 요청 여부를 판단할 수
1/5/2025
iOS에서 이벤트 기반 URL 요청이 잘 전송되는지 확인하기 (feat. 광고 트래킹.. 제대로 가고 있나요?)
안녕하세요 지마켓 Mobile Application Team 강수진입니다.오늘은 iOS에서 특정 이벤트에 대한 URL 요청이 정상적으로 이루어졌는지 확인하는 방법에 대해 알아보겠습니다.들어가기 전에모든 서비스에서 광고는 중요합니다. 왜냐하면 수익과 직결되기 때문이죠 지마켓도 곳곳에 다양한 유형의 광고가 포함되어 있는데요! 일례로 사용자가 광고 상품을 클릭하면, 해당 이벤트가 광고 처리 시스템으로 전송되어 광고가 집계되고, 이에 따라 비용이 청구될 수 있습니다.요구 사항광고 트래킹은 수익과 직결되기 때문에 문제가 생기면 최우선 순위로 대응해야 하는 이슈 중 하나입니다.그런데 코드 수정을 하다가 기존의 트래킹 코드가 동작을 안 하는 상황이 발생한다면요..?? 심지어 이런 데이터 트래킹의 이슈는 일반적인 QA로 발견되기 어려운데요...? 벌써 아찔하죠..? 그렇다면 배포 전 테스트를 통해 '광고 트래킹 이벤트가 발생했을때, 해당 URL 요청을 제대로 보내고 있는지' 확인할 수 없을까요??이번 프로젝트는 이러한 필요성으로부터 시작됩니다.어떻게 하면 좋을까?앞서 말했듯 '광고 이벤트가 발생하면, 광고 처리 시스템 URL 로 트래킹을 보낸다' 이것이 광고 시스템 처리에 대한 기본 전제입니다.하지만 트리거 이벤트가 발생했을때 진짜로 광고 URL 요청을 보냈는지 확신할 수 있나요? 정말요?? 이 사실을 어떻게 검증할 수 있을까요?기존에 트래킹 이벤트를 아래와 같이 sendTracking 함수에서 처리한다고 할때protocol AdTracker { func sendTracking()}struct AdTrackingClient: AdTracker { func sendTracking() { // URL Request 보냄 }}단순히 Fake 객체를 만들고, sendTracking 함수에서는 isTrackingSent 플래그를 변경하는 방식으로 트래킹이 되었는지 검증하면 될까요?struct FakeAdTrackingClient: AdTracker { var isTrackingSent = false func sendTracking() { isTrackingSent = true }}이와 같은 방식은 sendTracking 함수가 호출되었는지 여부만 확인할 수 있을 뿐, 실제로 URLRequest를 통해 네트워크 요청이 이루어졌는지는 확인할 수 없습니다. 실제 AdTrackingClientAdTrackingClient의 sendTracking 함수에서는 print("hello world")만 구현되어 있을지도 모르는 일이죠!따라서 저희는 실제 URL 요청을 캐치할 수 있는 proxy 를 만들어서 이벤트를 가로채기로 했습니다. 그리고 여기서 가로챈 URL 정보는 저장소에 별도로 저장해 둡니다.광고 트래킹 이벤트를 트리거 시킬 때 URL 요청을 제대로 보낸다면, 해당 URL 정보는 proxy에 의해 저장소에 저장될 겁니다.그럼 우리는 이벤트 트리거 후 URL 이 저장소에 있냐 / 아니냐에 따라서 이벤트에 따른 URL 요청 여부를 판단할 수
2025.01.05
좋아요
별로에요
CI 빌드 오류의 원인 분석에서 해결까지의 여정
LINE Plus의 MPR(Mobile Productive & Research) 팀은 LINE 클라이언트 앱의 빌드 개선과 CI 파이프라인 관리, 자동화 지원 등의 업무를 담당하고 있습니다. 이번 글에서는 저희 팀에서 운영하는 CI/CD에 발생했던 흔하지 않은 이슈와 그 해결 방법을 공유하려고 합니다. 이번 글에서 다룰 이슈는 문제가 발생한 시점부터 다시 정상적으로 CI/CD가 운영되기까지 약 10일 정도의 시간이 소요됐는데요. 추후 유사한 문제가 발생했을 때 어떤 식으로 문제의 원인을 찾고, 분석해서, 해결해 나가야 하는지 그 과정을 참고하고자 작성했습니다. 저희의 문제 해결 과정이 이 글을 읽고 계신 분들께도 도움이 되기를 바라며 시작하겠습니다.현재 MPR 팀에서 운영하고 있는 CI의 전체 구성을 간략하게 소개하겠습니다. 먼저 소스 리포지터리로 Git을 사용하고 있으며, Jenkins와 여러 플러그인을 이용해 CI를 운영하고 있습니다. 빌드 개선 및 오류 검토를 목적으로 Gradle을 활용한 빌드 정보를 Develocity에 수집하고 있으며, Jenkins 빌드 로그를 Logstash를 통해 Elasticsearch로 모아서 집계한 뒤 Kibana 및 Grafana를 사용해 빌드 정보를 시각화하고 있습니다.평소와는 다른 빌드 실패 증상의 발현언제부터인가 빌드 실패 알림이 증가했습니다. CI/CD를 운영하다 보면 예기치 못한 여러 문제가 발생할 수 있으며, 그중 빌드 오류가 발생하는 경우는 다음과 같습니다.• 테스트 관련 오류• 플레이키(flaky) 테스트: 코드는 동일한데 테스트 결과는 다른 경우• 느린 테스트: 테스트 실행하는 데 지나치게 오래 걸리는 경우• 인프라 및 성능 관련 오류• 서버 과부하: 동시에 여러 테스트를 처리하느라 서버나 네트워크에 과부하가 걸리는 경우• 확장성 문제: 개발 팀과 프로젝트의 규모가 커지면서 파이프라인이 증가된 부하를 처리하지 못하지만 구조상 확장하기 어려운 경우• 성능 이상: 서버의 응답이 지연되거나 메모리 누수가 발생하거나 부하 분산이 적절히 처리되지 않은 경우• 통합 및 배포 관련 오류• 도구 간 통합 문제: 내부적으로 인터페이스를 구축해 서로 다른 도구를 통합해서 사용하다가 예상치 못한 도구 간 설정 호환 문제가 발생하는 경우일반적인 경우 빌드 실패의 주요 원인은 유닛 테스트 증가에 따른 빌드 및 테스트 수행 시간의 증가입니다. Jenkins에 빌드 타임아웃 시간을 설정해 놓으면 빌드 및 테스트하는 데 이보다 시간이 오래 걸릴 경우 강제로 중단되는데요. 유닛 테스트가 늘어나 테스트 수행 시간이 증가하거나 일시적으로 자원이 부족해 테스트 수행에 실패하면서 설정해 놓은 빌드 타임아웃 시간을 초과하면 빌드에 실패합니다. 보통 이런 경우는 빌드에 사용할 리소스가 일시적으로 부족하거나 네트워크에 간헐적으로 문제가 생겨 발생하기 때문에 빌드를 다시 실행하면 대부분 재현되지 않습니다.저희는 이번 경우 역시 처음에는 이처럼 시간이 지나면 자연스럽게 해결될 일시적인 증상으로 간주하고 원인을 파악하기 시작했습니
elasticsearch
jenkins
nodejs
1/5/2025
CI 빌드 오류의 원인 분석에서 해결까지의 여정
LINE Plus의 MPR(Mobile Productive & Research) 팀은 LINE 클라이언트 앱의 빌드 개선과 CI 파이프라인 관리, 자동화 지원 등의 업무를 담당하고 있습니다. 이번 글에서는 저희 팀에서 운영하는 CI/CD에 발생했던 흔하지 않은 이슈와 그 해결 방법을 공유하려고 합니다. 이번 글에서 다룰 이슈는 문제가 발생한 시점부터 다시 정상적으로 CI/CD가 운영되기까지 약 10일 정도의 시간이 소요됐는데요. 추후 유사한 문제가 발생했을 때 어떤 식으로 문제의 원인을 찾고, 분석해서, 해결해 나가야 하는지 그 과정을 참고하고자 작성했습니다. 저희의 문제 해결 과정이 이 글을 읽고 계신 분들께도 도움이 되기를 바라며 시작하겠습니다.현재 MPR 팀에서 운영하고 있는 CI의 전체 구성을 간략하게 소개하겠습니다. 먼저 소스 리포지터리로 Git을 사용하고 있으며, Jenkins와 여러 플러그인을 이용해 CI를 운영하고 있습니다. 빌드 개선 및 오류 검토를 목적으로 Gradle을 활용한 빌드 정보를 Develocity에 수집하고 있으며, Jenkins 빌드 로그를 Logstash를 통해 Elasticsearch로 모아서 집계한 뒤 Kibana 및 Grafana를 사용해 빌드 정보를 시각화하고 있습니다.평소와는 다른 빌드 실패 증상의 발현언제부터인가 빌드 실패 알림이 증가했습니다. CI/CD를 운영하다 보면 예기치 못한 여러 문제가 발생할 수 있으며, 그중 빌드 오류가 발생하는 경우는 다음과 같습니다.• 테스트 관련 오류• 플레이키(flaky) 테스트: 코드는 동일한데 테스트 결과는 다른 경우• 느린 테스트: 테스트 실행하는 데 지나치게 오래 걸리는 경우• 인프라 및 성능 관련 오류• 서버 과부하: 동시에 여러 테스트를 처리하느라 서버나 네트워크에 과부하가 걸리는 경우• 확장성 문제: 개발 팀과 프로젝트의 규모가 커지면서 파이프라인이 증가된 부하를 처리하지 못하지만 구조상 확장하기 어려운 경우• 성능 이상: 서버의 응답이 지연되거나 메모리 누수가 발생하거나 부하 분산이 적절히 처리되지 않은 경우• 통합 및 배포 관련 오류• 도구 간 통합 문제: 내부적으로 인터페이스를 구축해 서로 다른 도구를 통합해서 사용하다가 예상치 못한 도구 간 설정 호환 문제가 발생하는 경우일반적인 경우 빌드 실패의 주요 원인은 유닛 테스트 증가에 따른 빌드 및 테스트 수행 시간의 증가입니다. Jenkins에 빌드 타임아웃 시간을 설정해 놓으면 빌드 및 테스트하는 데 이보다 시간이 오래 걸릴 경우 강제로 중단되는데요. 유닛 테스트가 늘어나 테스트 수행 시간이 증가하거나 일시적으로 자원이 부족해 테스트 수행에 실패하면서 설정해 놓은 빌드 타임아웃 시간을 초과하면 빌드에 실패합니다. 보통 이런 경우는 빌드에 사용할 리소스가 일시적으로 부족하거나 네트워크에 간헐적으로 문제가 생겨 발생하기 때문에 빌드를 다시 실행하면 대부분 재현되지 않습니다.저희는 이번 경우 역시 처음에는 이처럼 시간이 지나면 자연스럽게 해결될 일시적인 증상으로 간주하고 원인을 파악하기 시작했습니
2025.01.05
elasticsearch
jenkins
nodejs
좋아요
별로에요
Compose와 MVI로 다시 태어난 Android UI: MVVM에서 MVI로의 전환기
안녕하세요, 여기어때컴퍼니 Android 개발팀의 에이든입니다.최근 검색 화면을 웹에서 네이티브로 전환하는 프로젝트를 진행했습니다. 이 화면은 사용자 상호작용이 많고 데이터 갱신이 빈번하여, 효과적인 상태 관리가 필수적이었습니다. 이를 위해 기존의 MVVM 방식보다 단방향 데이터 흐름과 선언형 UI의 장점을 극대화할 수 있는 MVI 패턴을 선택했습니다. 이 과정에서 Jetpack Compose와 MVI 패턴을 결합하여, 더 직관적이고 효율적인 Android 개발 환경을 구축한 경험을 소개하고자 합니다.왜 MVI를 선택했을까?기존에 널리 쓰이던 MVVM은 안정적이고 익숙한 방식이지만, UI가 복잡하고 상태 변화가 잦은 화면에서는 관리 포인트가 늘어나는 단점이 있습니다.ViewModel에서 여러 상태를 관리하기 위해 다수의 프로퍼티를 생성하다 보면, 이를 View가 각각 관찰하면서 코드의 복잡성이 증가 했습니다.상태 변경과 UI 반영 간의 비동기 문제가 발생하거나, 예상치 못한 UI 갱신 이슈로 인해 디버깅이 어려운 경우가 많았습니다.Compose와 MVI를 도입한 이유Compose와 MVI는 이러한 문제를 해결하기 위해 상호 보완적으로 작동하며, 상태 관리와 UI 동기화를 효율적으로 처리하는 데 장점이 있습니다.Jetpack Compose선언형 UI로 간결하고 가독성 높은 코드를 작성할 수 있습니다.상태 변화에 따라 화면이 자동으로 재구성되어 UI 구현이 용이합니다.MVI 패턴단방향 데이터 흐름을 통해 상태 중심 개발을 가능하게 합니다.복잡한 UI 상태를 예측 가능하고 일관성 있게 관리할 수 있습니다.명확한 상태 전달 구조로 소스 코드 수정 및 디버깅을 더욱 쉽게 만듭니다.Compose와 MVI의 조합 효과MVI는 상태 변화를 명확히 전달하며, Compose는 이를 즉각적으로 UI에 반영합니다. 이로 인해:코드의 가독성과 간결성을 개선할 수 있었고,UI 상태 변화와 동기화 문제를 최소화하며,유지보수성을 높여 보다 효율적인 개발 환경을 구축할 수 있었습니다.MVI 패턴이란?본격적인 전환에 앞서 MVI 패턴에 대해 간단히 알아보겠습니다.MVI 패턴은 단방향 데이터 흐름을 통해 상태 중심의 구현을 할 수 있도록 설계되었습니다. 주요 구성 요소의 역할은 다음과 같습니다:Intent사용자의 액션이나 이벤트를 전달합니다.이벤트가 발생하면 이를 처리한 뒤 결과를 Model로 전달합니다.ModelView가 렌더링 되는 데 필요한 SSOT(Single Source of Truth)입니다.Immutable하며, 모든 상태 변경은 Intent를 통해 새로운 객체를 생성하는 방식으로 이루어집니다.ViewUI를 담당하며 사용자의 액션(Intent)을 전달합니다.Model을 구독하여 상태 변경에 따라 UI를 렌더링합니다.MVI 패턴의 흐름은 직관적입니다. 사용자의 액션(Intent)이 발생하면 Model의 상태가 변경되고, View는 변경된 상태를 기반으로 UI를 새롭게 렌더링합니다.일회성 작업과 Side Effects(부수효과)화면 전환이나 Toast 메시지 표
1/5/2025
Compose와 MVI로 다시 태어난 Android UI: MVVM에서 MVI로의 전환기
안녕하세요, 여기어때컴퍼니 Android 개발팀의 에이든입니다.최근 검색 화면을 웹에서 네이티브로 전환하는 프로젝트를 진행했습니다. 이 화면은 사용자 상호작용이 많고 데이터 갱신이 빈번하여, 효과적인 상태 관리가 필수적이었습니다. 이를 위해 기존의 MVVM 방식보다 단방향 데이터 흐름과 선언형 UI의 장점을 극대화할 수 있는 MVI 패턴을 선택했습니다. 이 과정에서 Jetpack Compose와 MVI 패턴을 결합하여, 더 직관적이고 효율적인 Android 개발 환경을 구축한 경험을 소개하고자 합니다.왜 MVI를 선택했을까?기존에 널리 쓰이던 MVVM은 안정적이고 익숙한 방식이지만, UI가 복잡하고 상태 변화가 잦은 화면에서는 관리 포인트가 늘어나는 단점이 있습니다.ViewModel에서 여러 상태를 관리하기 위해 다수의 프로퍼티를 생성하다 보면, 이를 View가 각각 관찰하면서 코드의 복잡성이 증가 했습니다.상태 변경과 UI 반영 간의 비동기 문제가 발생하거나, 예상치 못한 UI 갱신 이슈로 인해 디버깅이 어려운 경우가 많았습니다.Compose와 MVI를 도입한 이유Compose와 MVI는 이러한 문제를 해결하기 위해 상호 보완적으로 작동하며, 상태 관리와 UI 동기화를 효율적으로 처리하는 데 장점이 있습니다.Jetpack Compose선언형 UI로 간결하고 가독성 높은 코드를 작성할 수 있습니다.상태 변화에 따라 화면이 자동으로 재구성되어 UI 구현이 용이합니다.MVI 패턴단방향 데이터 흐름을 통해 상태 중심 개발을 가능하게 합니다.복잡한 UI 상태를 예측 가능하고 일관성 있게 관리할 수 있습니다.명확한 상태 전달 구조로 소스 코드 수정 및 디버깅을 더욱 쉽게 만듭니다.Compose와 MVI의 조합 효과MVI는 상태 변화를 명확히 전달하며, Compose는 이를 즉각적으로 UI에 반영합니다. 이로 인해:코드의 가독성과 간결성을 개선할 수 있었고,UI 상태 변화와 동기화 문제를 최소화하며,유지보수성을 높여 보다 효율적인 개발 환경을 구축할 수 있었습니다.MVI 패턴이란?본격적인 전환에 앞서 MVI 패턴에 대해 간단히 알아보겠습니다.MVI 패턴은 단방향 데이터 흐름을 통해 상태 중심의 구현을 할 수 있도록 설계되었습니다. 주요 구성 요소의 역할은 다음과 같습니다:Intent사용자의 액션이나 이벤트를 전달합니다.이벤트가 발생하면 이를 처리한 뒤 결과를 Model로 전달합니다.ModelView가 렌더링 되는 데 필요한 SSOT(Single Source of Truth)입니다.Immutable하며, 모든 상태 변경은 Intent를 통해 새로운 객체를 생성하는 방식으로 이루어집니다.ViewUI를 담당하며 사용자의 액션(Intent)을 전달합니다.Model을 구독하여 상태 변경에 따라 UI를 렌더링합니다.MVI 패턴의 흐름은 직관적입니다. 사용자의 액션(Intent)이 발생하면 Model의 상태가 변경되고, View는 변경된 상태를 기반으로 UI를 새롭게 렌더링합니다.일회성 작업과 Side Effects(부수효과)화면 전환이나 Toast 메시지 표
2025.01.05
좋아요
별로에요