티스토리 뷰

Tip and Error

"execSync" Node Buffer 문제 (업데이트)

geonwoopaeng@gmail.com 2024. 4. 10. 20:19

execSync Node Buffer 문제 (업데이트)

간단하게 업데이트 과정은 다음과 같습니다.

 

문제:

node_modulesfirebase 가 추가 될 시

데스크탑 앱 자동 업데이트가 진행되지 않습니다.

=> execSync(XCopy ... ... )까지 실행되고 그 이후 상황이 실행되지 않습니다.
업데이트 부분의 기존 파일과 교체 부분에서 문제가 발생했습니다.

 

원인:

**firebaseBuffer 크기(Node Buffer 란)가 커서 execSync 에서 받아드리지 못해서 생기는 문제**
(exec의 기본 버퍼 사이즈는 200k 입니다.)

 

해결책:

1. XCopy 를 parent process와 분리하여 실행 ({detached: true} 사용)

  • 실행 과정(cmd 창)이 보입니다.

 

2. XCopynpm i 합니다.(내부에서 node_modules 생성)

⇒ 기본적으로 node_modules를 가지고 있지 않고 파일을 옮긴 후 node_modules 만들기

  • Github에 올라가는 package.json 에는 firebase 빼야 합니다.
  • node 가 설치 되지 않은 컴퓨터에서는 동작하지 않습니다.

 

3. maxBuffer 옵션 사용

maxBuffer: Largest amount of data in bytes allowed on stdout or stderr.
  • stdout, stderr 값을 어느 정도까지 해야할 지 의문

stdout or stderr 값 파악하는 방법

1. Terminal 사용
$ls -l ${파일/폴더 명} //파일, 폴더들의 정보 출력
ex)  -rw-r--r-- 1 g w paeng 197121 816 Jul  8  2023  package.json

816 / 1024 * 1024 의 값이 해당 값입니다.

2. 내부 코드 사용
const { execSync } = require('child_process');

try {
    const stdout = execSync('your_command'); // 2>&1을 사용하여 stderr도 stdout으로 리다이렉트합니다.
    console.log('stdout:', stdout.toString());
} catch (error) {
    console.error('stderr:', error.stderr.toString());
}

대략 firebase에서 가장 큰 것이 5.xxMB 정도 했으니
10MB({ maxBuffer: 1024 * 1024 * 10 })로 설정하면 될 것 같아 다음과 같이 적용하였습니다.

 

4. try & catch 사용

문제가 생기는 Xcopy 쪽에 try & catch 를 적용하면 동작합니다.

  • 그냥 넘어가는 부분이 있기 때문에 확인 필요
const tmp_command = `Xcopy "${before_folder}" "${after_folder}" /E /H /C /I /y /r`;
try {
    let result = require('child_process').execSync(tmp_command);
} catch (error) {
    console.error("error :" error);
}

 

5. spawn 사용

spawn 사용에 앞서 exec와 비교부터 해보겠습니다.

exec: spawn 매서드를 이용하여 Shell을 실행시키고 해당 Shell에서 명령어 실행

  • Shell에서 제공하는 기능 이용 가능
  • 프로세스 간 데이터 통신에 이용되는 방식: Buffered
    • 자식 프로세스의 데이터를 차곡차곡 쌓아 한번에 전달하기 때문에 하나의 콜백에서 모든 수신이 가능

spawn: 새로운 프로세스를 띄워 명령어 수행

  • 프로세스 간 데이터 통신에 이용되는 방식: Stream
    • 실시간으로 데이터를 수신할 수 있어야하기 때문에 이벤트 등록 방식으로 데이터를 주고 받음

문제가 발생하는 부분이 XCopy 명령어가 필요한 부분입니다.
spawn이 Buffer에 상관없지만 실시간, 쉘 필요하기 때문에 exec를 사용하게 되었습니다.

 

마치며

다음과 같이 3번과 4번을 혼합하여 사용하는 방법으로 결정을 하게되었습니다.

const tmp_command = `Xcopy "${before_folder}" "${after_folder}" /E /H /C /I /y /r`;
try {
    let result = require('child_process').execSync(tmp_command, {maxBuffer: 1024 * 1024 * 10});
} catch (error) {
    console.error("error :" error);
}

1번, 2번 해결책을 생각했을 때는 Buffer 문제라는 것도 파악하지 못했습니다.
(에러 메세지도 나오지 않았다....)
그래도 하나하나 하다보니 문제를 해결하게 되었습니다. 그냥 다양한 방법으로 부딪쳐야 겠습니다.

긴 글 읽어주셔서 감사합니다.

반응형
공지사항
최근에 올라온 글