일단 오자마자 파일 마이그레이션 데이터를 확인했는데

데이터가 1만건이 넘기 때문에 하나당 1분이 걸린다고 해도 일주일 이상 24시간 돌아가야 하는 양이었고

개체 하나에 해당하는 레코드라 다른 곳들에도 많을 경우 현재 방식으로는 답이 없어보였다.

 

일단 배치방식으로 분할해서 보내는 방법을 확인해봤지만

6개정도를 promise를 통해서 발송하는 내용인 것 같고

실제로 테스트해보지 않아서 얼마나 속도차이가 있는지는 모르겠지만

promiseall 등으로 진행한다면 하나의 파일 용량이 크면 효과가 많이 떨어질 것 같고

개별적으로 6개씩 분할해서 6개 각각 링크 연결을 해서 진행하기에도 조금 애매해보였다.

 

그렇다고 전체 내용의 용량들을 따로 발송해서 6등분을 하고 나눠서 보내는 것도 이상하고

파일 마이그레이션 부분의 우선순위는 당장은 낮은 상태라 다른 작업을 먼저 하고 알아보기로 했다.

 

이전에 진행한 인터페이스의 개체 변경으로 새로운 개체 내부에 필드를 만들었었는데

연관된 다른 개체의 필드들도 맞춰서 수정해야 했고 관계를 재설정해야 했다.

 

중간에 유지보수가 계속 들어왔는데

이전에 진행한 웹사이트 이전 관련된 부분에서는 테스트 환경 문의라 빠르게 답변할 수 있었지만

수량 합산 로직에 문제가 발생한 부분은 간단하게 답변했지만 고객사쪽에서 처리가 불가능한 부분이었다.

 

개체변경으로 인해 영향받은 트리거를 수정해주고

영향받은 4개 중 파일수신 관련 인터페이스를 수정하고 테스트까지 마무리했다.

 

다른 org의 인터페이스도 통으로 이전한다고 하는데

해당 업무를 담당 희망하는 사람이 있냐고 하셨지만

현재 프로젝트 진행되는 org가 3개인 상태고

간간이 다른 org들에서도 계속 유지보수가 들어오고 있는데

통으로 시간을 비우지 않는 이상 애초에 들어갈 수 없어보였다.

 

다르 팀원분이 담당하시기로 하면서 팀장님은 그쪽 지원을 도와주기로 하셨고

그 대신 또 팀장님이 담당하시는 업무가 넘어온다고 하는데

어중간한 프로젝트들을 계속 처리하느니 하나 제대로 처리하는게 차라리 편할 것 같기도 하고

계속 회사만 바뀌면서 얊게 이해하고 인터페이스만 처리하다보니

처음부터 끝까지 프로세스를 진행한 인터페이스는 아직 없는 것 같다.

 

해당하는 개체가 너무 많은데

이번엔 클레임 관련 인터페이스 필드 논의가 들어갔고

DB to DB라 쓸대없는 필드를 전부 정의서에 넣어버렸는데

수신할 때는 진짜 쓸모없더라도 그냥 필드에 값을 넣어주면 되겠지만

SFDC에서 발송하게 하는 경우 없는 데이터를 전송할 수 없고

이게 있는지 없는지 각 필드마다 전수조사를 해야 하기 때문에 시간 지연이 엄청났다.

 

결국 클레임 관련 가능한 맵핑만 진행한 다음

나머지 필드들에 대해서는 실제 사용하는건지 다시 확인 요청을 발송했다.

 

수량합산 로직 관련해서 다시 회의가 열렸는데

문제가 발생한 부분은 Select를 해서 현재 수량을 체크해주는데

추가 또는 취소 인터페이스가 ms 단위로 동일하게 들어올 경우

a, b 레코드 인터페이스의 값이 SFDC에 반영되기 전에

a, b 레코드에서 기존에 있던 값을 가져와서 추가한 값이 저장되기 때문에

sum + a, sum + b 중 하나가 업데이트 되어서

필요한 값인 sum + a + b가 반영되지 않는 문제가 발생했다.

동일 인터페이스 A, B 호출 시 순서

 

해당 문제는 사용자가 순차적으로 몇초 이상의 간격을 두고 작동되기 때문에 문제가 없었지만

중간처리하는 서버들이 존재했기 때문에 쌓였다 한번에 발송하게 되면 엄청 낮은 확률로 이런 문제가 발생했고

이걸 해결하기 위해서 rollup을 사용하면 어떤지에 대한 이야기가 나왔지만

trigger 작동 시점에 따라서 트랜잭션 분리가 된 경우 rollup의 값을 가져오더라도

각각의 트랜잭션 내부에서 바라보는 rollup의 값은 다를 것 같다는 의견도 있었고

필드 자체를 rollup으로 대체하자는 의견도 있지만

이미 운영에 배포까지 끝난 로직이기 때문에 엄청나게 많은 개체, flow, apex 등에서 사용되고 있어서

단순히 필드 타입을 변경해서 값을 가져다 쓰는 것으로 마무리할 수는 없었다.

 

갑작스럽게 trigger, 트랜잭션, rollup에 대한 생명주기(?) 토론이 시작되었는데

실제로 초 대규모 실시간 인터페이스라면 할법한 고민이기도 하고

각자 의견이 다 같지도 않고 중점적으로 문제점이라고 보는 타이밍도 조금씩 다르기도 해서 재미있었다.

 

원자성, 고립성 등 여러가지 생각이 되기도 했는데

일단은 동시에 하나의 레코드에 작용하려고 하는 작업이라 문제가 되기 때문에

여태까지 딱 한번 최근에 발생한 내용이라 현재 로직은 유지하면서 실시간으로 볼 수 있게 하고

현재 일일 처리량 자체는 많지 않기 때문에 스케쥴을 걸어서 1분 뒤 다시 점검하게 하는 방식으로 마무리했다.

 

주로 담당했던 고객사 관련 담당자분이 출산휴가로 1년 반이상 안계시게 됐는데

언질 없이 갑작스럽게 당일부터 사라져버려서 우리쪽도 당황했지만 고객사도 당황했던 것 같고

여태까지 업무 진행이 대부분 중단되어버리고 정리가 제대로 되지 않아서

우리쪽 어드민분이 전체 작업 및 중단내역을 정리하고 계셨고

출고, 납품, 세금계산, 송장 프로세스에 대한 설명과 중단된 위치

그리고 다우오피스 연동, 여신처리 등에 대해 전달드렸다.

 

 

(1).백준 11637번 인기 투표는 각각의 투표들을 받았을 때

과반수 우승자, 우승자, 우승자 없음 등의 결과를 출력해야 하는 문제였다.

 

일단 테스트케이스를 for문 내부에서 분할해서 승자체크 메서드를 호출하고

승자체크 메서드에서는 합을 reduce로 미리 지정하고

max값은 구조분해할당과 Math.max를 통해서 지정해준 다음

max값이 total / 2보다 큰 경우 과반수기 때문에 index를 찾아서 반환하고

filter를 통해 max값이 2개 이상인 경우 우승자가 없기 때문에 우승자 없음을 반환하고

마지막으로 우승자가 존재하는 상황이기 때문에 과반수가 아닌 우승자의 index를 찾아서 반환한 다음

반환받을 때마다 result에 값을 담아서 한번에 출력하는 방식으로 해결했다.

const input = `4
3
10
21
10
3
20
10
10
3
10
10
10
4
15
15
15
45`.split('\n').map(Number)

const result = []
const checkWinner = (arr) => {
    const total = arr.reduce((a,b) => a+b)
    const max = Math.max(...arr)
    if(arr.filter(el => el > total / 2).length){
        return 'majority winner ' + (arr.indexOf(max) + 1)
    }
    else if(arr.filter(el => el == max).length > 1){
        return 'no winner'
    }
    else{
        return 'minority winner ' + (arr.indexOf(max) + 1)
    }
}

for(let i = 1 ; i < input.length ; i++){
    let length = input[i]
    const testArr = [...input.slice(i + 1, i + length + 1)]
    result.push(checkWinner(testArr))
    i += length
}

console.log(result.join('\n'))

'회고' 카테고리의 다른 글

[개발일지] - 586(주말)  (0) 2025.02.08
[개발일지] - 585  (0) 2025.02.07
[개발일지] - 583  (0) 2025.02.05
[개발일지] - 582  (0) 2025.02.04
[개발일지] - 581  (0) 2025.02.03

+ Recent posts