프로그래밍/Frontend (React, Javascript, Typescript)

[JavaScript, Node.js] 프론트엔드(JavaScript Runtime)에서의 Race Condition

Turtle-hwan 2024. 4. 11. 18:11

JS와 관련해서 흥미로운 사실을 찾았다.

시스템프로그래밍이나 OS 수업에서 한 번쯤 들어봤을 race condition이 프론트엔드에서도 발생할 수 있다는 것이다.

 

Race Condition?

race condition은 두 개 이상의 프로세스, 스레드가 공유되는 자원(critical section)에 접근해서 값을 쓰려고 할 때 발생한다.

race condition이 발생하면 공유 자원의 값이 의도치 않게 변경되는 문제점이 생긴다.

백엔드에서의 레이스 컨디션은 실제 바뀐 값으로 권한 상승 등이 일어날 수 있어 CTF에서도 종종 출제되고 보안적으로 상당히 심각하게 다뤄지는 문제이다.

반면 프론트엔드에서는 보여지는 화면만 바뀌는 것이니 그렇게까지 위험하지는 않을 것 같고, Race Condition이 발생할 수 있는지를 생각해본 적이 없었는데 이번 기회에 알아보게 되었다.

JS Engine은 싱글 스레드인데 어떻게 Race Condition이 발생하는가?

그런데 JS Engine은 싱글 스레드 기반인데 어디서 레이스 컨디션이 발생하는 건지 궁금증이 생겼다.

JS 런타임의 안의 memory heap과 call stack은 싱글 스레드 상에서 동작하니 문제가 없어 보인다.

그렇다면 JS 런타임의 DOM, fetch 등 Web API 스레드들이 callback queue에 동시에 접근하는 것이니, callback queue에서 race condition이 발생하는 것일까?

 

이 코드는 JavaScript에서 Race Condition이 발생하는 예시이다.

var x = 1;

async function foo() {
    var y = x;
    await setTimeout(100); // whatever async here
    x = y+1;
}

//비동기 함수를 동시에 실행하면 Race condition이 발생한다.
await Promise.all([foo(), foo(), foo()]);
console.log(x); // 2


//동시에 실행되지 않고 순차적이라면 다음과 같다.
await foo();
await foo();
await foo();
console.log(x); // 4

아래 Stackoverflow 답변을 참고하면, 동시성(Concurrency)과 병렬성(Parallel)에 관해 JS는 싱글 스레드 기반이므로 스레드 병렬성은 없지만 비동기 함수를 가져서 동시성을 가지고 작동한다.

동시성 때문에 JS에서 여러 비동기 요청(fetch, setTimeout ..)을 여러 번 보냈을 때 그 응답은 순서가 보장되지 않는다. 

따라서 await 등으로 순서를 보장해 주지 않으면 DOM이나 변수에 원하지 않는 값이 들어갈 수 있다.

https://stackoverflow.com/questions/73202786/does-this-javascript-example-create-race-conditions-to-the-extent-that-they

 

Does this JavaScript example create “race conditions”? (To the extent that they can exist in JavaScript)

I am aware JavaScript is single-threaded and technically can’t have race conditions, but it supposedly can have some uncertainty because of async and the event loop. Here’s an oversimplified example:

stackoverflow.com

 

JS 엔진을 쓰는 Node.js에서의 Race Condition과 이를 막기 위한 방법

Race Condition을 막는 방법은 SystemProgramming에서 나오는 것과 같다. 공유되는 자원 Critical Section에 접근하는 것을 한 번에 하나씩 접근하도록 제한하면 된다.

JS 엔진을 쓰는 Node.js 계열에서도 레이스 컨디션을 막기 위한 mutex, semaphore 라이브러리가 구현되어 있다.

https://fourjae.tistory.com/entry/Nodejs-Race-Condition

 

[Node.js] Race Condition과 해결 원리

본 글에서는 Node.js에서 발생할 수 있는 Race Condition에 대해 작성하려고 한다. + 첫 프로젝트인 새싹챌린지를 진행하면서 겪었던 일까지 1. Race Condition이란? Race Condition(경쟁 상태) 혹은 경쟁 조건이

fourjae.tistory.com

 

  • 조금 더 찾아보니 threading과 concurrency(동시성)은 별개의 개념이고, 싱글 스레드에서도 동시적 접근으로 인한 race condition이 발생할 수도 있다고 한다.

싱글스레드 Node.js에서 race condition 예시 : https://stackoverflow.com/questions/21438207/can-node-js-code-result-in-race-conditions

 

Can node.js code result in race conditions?

From what I read, race conditions occur when different threads try to change a shared variable, which can result in a value that's not possible with any serial order of execution of those threads. ...

stackoverflow.com

 

참고 자료

https://velog.io/@pjc0247/프론트엔드와-Race-Condition

 

프론트엔드와 Race Condition

간단히 말해서 두 개 이상의 스레드가 하나의 공유 자원에 접근해서 일어나는 상태(혹은 그로 인해 발생하는 버그) 라고 생각하시면 됩니다.레

velog.io

https://tecoble.techcourse.co.kr/post/2021-09-12-race-condition-handling/

 

비동기 처리 시 race condition 고려하기

비동기 처리 시 race condition…

tecoble.techcourse.co.kr

https://jsremote.jobs/tutorials/race-condition/

 

What is the race condition in JavaScript? | Web developer jobs

What is race condition in details, and more definitive JavaScript guides and tutorials on JS-Remote-Jobs.

jsremote.jobs