Typescript reducer object key type
문제reduce를 이용해 빈 객체에 대상 배열의 string 값을 key로 사용해 값을 지정하려고 했더니 타입 에러가 발생했다. 12345const arr = [{name: 'a', value: 'val-a'}, {name: 'b', value: 'val-b'}, {name: 'c', value: 'val-c'}];const names = arr.reduce((acc, cur) => { acc[cur.name] = cur[value];}, {}) acc[key] Element implicitly has an ‘any’ type because expression of type’string’ can’t be used to index type...
webpack 빌드 속도 향상시키기
webpack 빌드가 갑자기 너무 느려져서 개발 속도가 정체되었다. 최근 webpack 옵션을 바꾼 적이 있었는데 그 때문인가 하고 성능과 관련된 옵션들을 살펴보다 잘못 사용하고 있던 부분을 발견했다. devtool 옵션devtool 옵션은 webpack의 소스맵 생성 여부를 제어한다. 나는 처음 생성할 때 되어있던 설정을 그대로 사용하고 있었는데 eval-source-map 이었던 걸로 기억한다. webpack 공식 홈페이지에 따르면, 해당 옵션의 build 속도는 가장 느리다고 나와있다. 가이드를 따르면 production용으로는 none을 사용하고, 개발용으로는 eval 을 사용할 것을 추천하고 있다. babel-loader & ts-loaderjs로 작성되어있던 프론트 코드들을 시간이 날 때마다 ts로 전환하고 있다. webpack에서 typescript를 사용하는 방법은 babel-loader를 사용하는 것과 ts-loader를 사용하는 방법 두 가지가...
Nest.js dependency injection constructor & property based
NestJS에는 dependency injection을 하는 다양한 방법이 존재한다. base service를 상속받는 구조로 작성하던 중 construction의 코드가 계속해서 반복되는 현상(bolerplate code)이 나타나 대안을 찾아보니 property based injection을 사용하면 코드 반복을 없앨 수 있음을 알게되었다. 두 방식의 장점과 단점을 정리해두려고 한다. Boilerplate code클래스에 많은 의존성이 있을 경우 각 의존성을 생성자에서 받아와 저장해야 하는데, 이 경우 생성자 코드가 길어지고 비슷한 코드가 반복된다. 이런 코드를 bolierplate code라고 한다. 1234567891011121314151617// Dependency Aclass ServiceA {}// Dependency Bclass ServiceB {}// Dependency Cclass ServiceC {}//...
React Native New Architecture
React Native는 버전 0.68부터 새로운 구조를 도입했다. 새로운 구조는 기존 구조에 있던 RN의 고질적인 성능 이슈를 해결했다. 하지만 기존 구조를 바탕으로 만들어진 라이브러리가 많기 때문에 기존의 프로젝트를 마이그레이션 하는 것은 충분히 고려해 본 다음 진행해야 할 것 같다. Old Architecture React Native는 크로스 플랫폼 애플리케이션을 개발하게 해준다. 이 말은 즉 각 OS의 Native 계층에 직접적으로 접근하지 않는다는 것이다. 그러므로 개발자가 작성한 JS 코드를 Native 세계에서 이해할 수 있도록 하는 별도의 과정이 필요했다. 기존의 구조에서는 JS로 작성된 모든 데이터가 serialize 과정을 거쳐 Bridge 라고 하는 컴포넌트를 통해 네이티브 레이어로 전달된다. Bridge를 일종의 ‘버스’라고 생각해 볼 수 있겠다. 전달받은 데이터는 deserialize 되어 데이터를 읽어 필요한 동작들이 실행된다. React...
Wowza Streaming Engine으로 LL-HLS 스트리밍 하기
HLS와 LL-HLSLL-HLS는 기존의 HLS를 확장한 프로토콜이다. HLS는 미디어를 segment라는 쪼개진 단위로 잘라 전송하는 프로토콜인데 segment duration 만큼의 latency가 발생할 수 밖에 없는 한계점을 가지고있다. HLS가 처음 발표되었을 때 기본 스펙에서는 30초의 latency를 가지고 있었으나 스트리밍 서버 튜닝으로 8~10초대로 latency를 낮추는 것이 가능했다. LL-HLS는 HLS와 달라진 동작 방식으로 latency를 2-8초 대로 단축시킨다. 차이점두 프로토콜의 차이점을 간단하게 살펴보면 아래와 같다. HLS의 segment가 더 작은 단위로 쪼개진다. 이 mini segment는 segment가 오래 지속되는 것에 비해 짧은 시간만 존재한다. playlist가 Preload Hints 정보를 가지고 있으며 이를 통해 다운로드되어야 하는 데이터릐 크기를 미리 알 수 있다. 이를 통해 오버헤드가 줄어든다. 하지만 필수적으로...
[AWS] SQS batch item failures
Snowball anti-patternsSQS에서 실패 처리된 메세지 핸들링은 매우 중요하다. 보통의 경우 Lambda가 batch를 처리하다 에러가 발생하는 경우 전체 메세지가 큐에 다시 들어가게 된다. 예를 들어 배치 크기가 100인 경우 한 번에 100개의 메세지가 처리되는 건데 77번째 메세지 처리 중 에러가 발생 할 경우 성공적으로 처리된 메세지를 포함한 전체 100개의 메세지가 다시 큐에 나타나게 된다. 결과적으로 같은 메세지가 여러 번 처리될 것이다. Dead-letter 큐가 있는 경우 실패한 메세지가 그곳으로 이동하겠지만 그렇지 않은경우 source 큐에 계속해서 다시 들어가게 되고 계속적인 메세지 처리 실패 후에는 유효 메세지 수 보다 실패했던 메세지의 수가 많아져 문제가 눈덩이처럼 불어날 것이다. 이 경우 아래와 같은 부가적인 문제들로 이어진다. 사용자 경험의 저하: batch 처리에 시간이 오래걸린다. 또는 전혀 처리되지 않을 수도 있다. 사용 비용...
[AWS] DLQ(Dead Letter Queue) 리드라이브
DLQSQS에서 DLQ(dead-letter queue)란 성공적으로 처리되지 않은 메세지를 담고있는 큐를 말한다. DLQ는 자동으로 설정되는 것은 아니고, 일단 큐를 생성한 후 해당 큐를 다른 큐의 DLQ로 설정하여 사용할 수 있다. DLQ도 소스 큐와 같은 유형의 큐여야 한다. FIFO 큐의 DLQ는 FIFO 큐가 되어야 하는 것이다. (스탠다드 큐도 같다) DLQ는 큐 생성 시에도 설정할 수 있고 생성 후에도 큐 편집 메뉴의 배달 못한 편지 대기열에서 설정 가능하다. DLQ 리드라이브 정상 처리되지 못한 메세지를 DLQ에서 다른 큐로 보내는 것을 ‘리드라이브’라고 한다. 큐 리드라이브는 원래 메세지를 처리하는 소스 큐로 보내는 것이 일반적이지만 다른 큐에서 처리되도록 할 수도 있다. DLQ로 지정된 큐는 콘솔에서 DLQ 리드라이브 버튼이 활성화 된 것을 확인 할 수 있다. 이 때 메세지 처리 정책을 정할 수 있다. maxReceiveCount는 최대 재처리 횟수를...
[AWS] aws-sdk v3 마이그레이션 (Node.js 18.x 런타임)
serverless로 Labmda를 컴파일하는데 aws-sdk v3를 사용하라는 warning이 계속 나타나서 이참에 업그레이드를 하기로 했다. AWS에서 sdk-v3로 코드를 바꿔주는 커맨드가 있긴한데 난 그걸로는 부족해서 이참에 리팩토링도 진행했다.v3로 버전업 되면서 달라진 점이 몇 가지 있는데 장점이 많아 업그레이드 할 시간이 있다면 바꿔보는 게 좋을 것 같다. modular package이전에는 aws-sdk 라이브러리 전체를 import해서 사용해야 했다. 1import {SNS} from "aws-sdk"; 이제 필요한 모듈만 import해서 사용할 수 있다. 1import { SNSClient } from "@aws-sdk/client-sns"; 이렇게 전체 라이브러리가 아닌 modular package를 사용하면 전체 번들러의 크기가 줄어들기 때문에 성능 향상에 도움이 될 수 있다....
[Error] Typescript process.env undefined 이슈
아무 세팅없이 process.env를 사용하면 그 타입은 string|undefined이다. 타입스크립트가 실제로 그 환경 변수가 있는지 알 수 없기 떄문이다. 그래서 타입에러가 가끔 발생한다. 12345678const dynamoDBClient = new DynamoDBClient({ endpoint: process.env.DYNAMO_ENDPOINT, region: process.env.REGION, credentials: { accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_ACCESS_KEY, }, }) 이렇게 작성할 경우 DynmoDBClient 생성자 파라미터 옵션이 모두 string으로 되어있기 때문에 타입에러가 발생한다. TS2322: Type ‘string | undefined’ is not...
[CS] Singleton pattern(JS)
Singleton pattern은 생성자가 여러 차례 호출되더라도 실제 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초 생성자가 생성한 객체를 리턴하는 디자인 유형이다. 주로 공통된 객체를 여러개 생성해 사용하는 Database Connection Pool과 같은 상황에서 많이 사용된다. 몇 가지 단점도 있는 패턴이다. Single responsibility 원칙을 저해한다. 두 가지 문제를 한 번에 해결해버리는 패턴이다. 한 가지는, ‘하나의 클래스는 하나의 인스턴스만 가질 것’ 다른 문제는 ‘단 하나의 클래스 인스턴스로 글로벌 액세스 포인트를 제공할 것’이다. 유닛 테스트를 작성하기 힘들어진다. 글로벌 변수의 현재 상태는 실행 순서에 따라 값이 달라지기 때문이다. 또한 글로벌 인스턴스이기 때문에 테스트 중 다른 컴포넌트가 상태를 변화시킬 수 있어 디버깅이 어려워질 수 있다. 자바스크립트에서 singleton pattern을 구현하는 방법은 여러가지가...