Design: 비동기/약속 지원

에 λ§Œλ“  2018λ…„ 01μ›” 07일  Β·  7μ½”λ©˜νŠΈ  Β·  좜처: WebAssembly/design

λ§Žμ€ JavaScript λΌμ΄λΈŒλŸ¬λ¦¬κ°€ 비동기식이며 WebAssemblyκ°€ 아직 Promiseλ₯Ό μ§€μ›ν•˜λŠ” 것을 보지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.
JS μ—μ½”μ‹œμŠ€ν…œμ„ ν™œμš©ν•˜λŠ” κ³ μ„±λŠ₯ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‰½κ²Œ μž‘μ„±ν•˜λ €λ©΄ κ°€μ Έμ˜¨ ν•¨μˆ˜μ— promise 지원을 μΆ”κ°€ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ λ‹€μŒκ³Ό 같이 μž‘λ™ν•΄μ•Ό ν•©λ‹ˆλ‹€.

const importObject = { 
  returnOneAsync: () => new Promise(done => done(1)) 
};
extern "C" int returnOneAsync();

int main(){
  int x = returnOneAsync(); // should suspend main until promise resolved.
  return x+x;
}

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ‚˜λŠ” 당신이 μ›Ήμ˜ 계산 λͺ¨λΈμ„ 잘λͺ» μ΄ν•΄ν•˜κ³  μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. JavaScriptλŠ” 닀쀑 μŠ€λ ˆλ“œκ°€ μ•„λ‹ˆλ―€λ‘œ 계산을 μΌμ‹œ μ€‘λ‹¨ν•˜λ©΄ 엔진과 μ‹€μ œλ‘œ 이λ₯Ό ν˜ΈμŠ€νŒ…ν•˜λŠ” 전체 λ Œλ”λŸ¬κ°€ μ€‘λ‹¨λ©λ‹ˆλ‹€. νŽ˜μ΄μ§€κ°€ μ •μ§€λ˜κ³  λ‹€λ₯Έ μ½”λ“œλŠ” μ‹€ν–‰ν•  수 μ—†μŠ΅λ‹ˆλ‹€(λ³„λ„μ˜ μž‘μ—…μž μ œμ™Έ). ν˜„κ°€μž₯μΉ˜κ°€ 날아가도둝 ν•˜λ €λ©΄ 연속성을 κ΅¬μ²΄ν™”ν•˜κ³  λ‚˜μ€‘μ— λ³΅μ›ν•˜λŠ” 방법이 ν•„μš”ν•©λ‹ˆλ‹€. μ΄λŠ” ν˜„μž¬ 엔진이 ν•  수 μžˆλŠ” μž‘μ—…μ΄ μ•„λ‹™λ‹ˆλ‹€.

λͺ¨λ“  7 λŒ“κΈ€

JS μ•½μ†μ˜ λͺ¨λ“  지원은 JS 호슀트 바인딩 μ œμ•ˆμ˜ 일뢀여야 ν•©λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ C μžμ²΄κ°€ 비동기 μ‹€ν–‰ 및 μΌμ‹œ 쀑단을 이해해야 ν•˜κΈ° λ•Œλ¬Έμ— κ·€ν•˜μ˜ μ˜ˆμ—μ„œ μ œμ•ˆν•œ κ²ƒμ²˜λŸΌ μž‘λ™ν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ κ·€ν•˜μ˜ μ˜ˆμ œμ—λŠ” 비동기가 μ—†μœΌλ©° 단지 약속을 μƒμ„±ν•˜λ―€λ‘œ λ™λ“±ν•œ μ½”λ“œλŠ” JS μžμ²΄μ—μ„œ μΌμ‹œ μ€‘λ‹¨λ˜μ§€ μ•Šκ³  "[object Promise][object Promise]" 와 같은 λ¬Έμžμ—΄μ„ μƒμ„±ν•©λ‹ˆλ‹€.

λ˜ν•œ κ·€ν•˜μ˜ μ˜ˆμ—λŠ” 비동기가 μ—†μŠ΅λ‹ˆλ‹€.

음, 이벀트 루프가 약속을 μ²˜λ¦¬ν•  λ•ŒκΉŒμ§€ 값을 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
μ•„μ΄λ””μ–΄λŠ” 값을 μ‚¬μš©ν•  수 μžˆμ„ λ•ŒκΉŒμ§€ μ›Ή μ–΄μ…ˆλΈ”λ¦¬ μ—”μ§„μ˜ 싀행을 μΌμ‹œ μ€‘λ‹¨ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
제곡된 μ˜ˆλŠ” λ¬Όλ‘  맀우 μ‚¬μ†Œν•©λ‹ˆλ‹€. 보닀 ꡬ체적인 μ˜ˆλŠ” λ„€νŠΈμ›Œν¬λ₯Ό 톡해 db 쿼리λ₯Ό λ§Œλ“œλŠ” κ²ƒμž…λ‹ˆλ‹€. getAgeOf: (name) => db.find({name}).then(x=>x.age)

C μžμ²΄λŠ” 비동기 μ‹€ν–‰ 및 μΌμ‹œ 쀑단을 μ΄ν•΄ν•˜μ§€ λͺ»ν•˜μ§€λ§Œ

그것은 잘λͺ»λœ κ²ƒμž…λ‹ˆλ‹€. C에 λŒ€ν•œ λ‹€μ–‘ν•œ 코루틴 κ΅¬ν˜„μ΄ μžˆμŠ΅λ‹ˆλ‹€.
λ˜ν•œ LLVM-5.0 이상은 코루틴 및 async/awaitλ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.

https://llvm.org/docs/Coroutines.html

그리고 C++17의 λΆ€λ‘μœΌλ‘œ clang-5.0λΆ€ν„° κ΅¬ν˜„λœ 코루틴 -tκ°€ μžˆμŠ΅λ‹ˆλ‹€.
이미 μ‚¬μš© 쀑인 λͺ‡ 가지 μ‹€ν—˜ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μžˆμŠ΅λ‹ˆλ‹€.
https://github.com/lewissbaker/cppcoro#generator

Cμ—μ„œ 코루틴 κ΅¬ν˜„μ€ JavaScript의 이벀트 루프와 마술처럼 μƒν˜Έ μš΄μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ˜ν•œ 일반적으둜 κ΅¬ν˜„λ³„ λ™μž‘μ— μ˜μ‘΄ν•©λ‹ˆλ‹€. μ½”λ£¨ν‹΄μ΄λ‚˜ 비동기와 같은 것을 μ•ˆμ •μ μ΄κ³  이식 κ°€λŠ₯ν•˜κ²Œ κ΅¬ν˜„ν•˜λ €λ©΄ μ–Έμ–΄μ—μ„œ κ΅¬λΆ„λœ 연속 ν˜•νƒœκ°€ ν•„μš”ν•©λ‹ˆλ‹€. Cκ°€ μ œκ³΅ν•΄μ•Ό ν•˜λŠ” κ°€μž₯ κ°€κΉŒμš΄ 것은 longjmp인데, μΆ©λΆ„ν•˜μ§€ μ•Šκ³  ν˜„μž¬ Wasm μžμ²΄μ—μ„œ κ΅¬ν˜„ν•  수 μ—†μŠ΅λ‹ˆλ‹€(Emscripten을 μ‚¬μš©ν•˜λ©΄ longjmpλŠ” JS μ˜ˆμ™Έκ°€ μžˆλŠ” JSμ—μ„œ κ΅¬ν˜„λ¨). Wasm은 ν˜„μž¬ 쀑단을 ν‘œν˜„ν•  수 μ—†μ§€λ§Œ κ²°κ΅­ μ΄λŸ¬ν•œ 라인을 따라 무언가λ₯Ό μΆ”κ°€ν•  κ³„νšμ΄ μžˆμŠ΅λ‹ˆλ‹€. C++ 코루틴은 아직 ν‘œμ€€μ΄ μ•„λ‹ˆλ©° Emscripten AFAICTμ—μ„œ μ²˜λ¦¬ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 당신이 μ–΄λ””μ—μ„œ μ˜€λŠ”μ§€ λ΄…λ‹ˆλ‹€.
제 생각을 μΆ©λΆ„νžˆ ν‘œν˜„ν•˜μ§€ λͺ»ν•œ 것 κ°™μ•„μš”.
C/C++μ—μ„œ μ½”λ£¨ν‹΄μ΄λ‚˜ 약속을 μ§€μ›ν•˜κ±°λ‚˜ wasm λ°”μ΄νŠΈμ½”λ“œμ—μ„œ 이λ₯Ό μ‹€ν˜„ν•˜μžλŠ” 것이 μ•„λ‹™λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ C μžμ²΄κ°€ 비동기 μ‹€ν–‰ 및 μΌμ‹œ 쀑단을 이해해야 ν•˜κΈ° λ•Œλ¬Έμ— κ·€ν•˜μ˜ μ˜ˆμ—μ„œ μ œμ•ˆν•œ κ²ƒμ²˜λŸΌ μž‘λ™ν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

Cκ°€ 비동기 싀행을 μ΄ν•΄ν•˜λŠ” 것이 μ™œ ν•„μš”ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆκΉŒ?

약속이 해결될 λ•ŒκΉŒμ§€ wasm μ‹€ν–‰ 엔진을 μΌμ‹œ μ€‘λ‹¨ν•˜λŠ” 기술적인 어렀움은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

wasm은 미리 x86으둜 μ»΄νŒŒμΌν•΄μ•Ό ν•˜μ§€λ§Œ μ‹€ν–‰ 흐름을 μ œμ–΄ν•  수 μ—†λ‹€λŠ” μ˜λ―ΈλŠ” μ•„λ‹™λ‹ˆλ‹€.
싀행을 μ€‘μ§€ν•˜λŠ” 일반적인 방법은 ptrace와 같은 ν•˜λ“œμ›¨μ–΄ μΈν„°λŸ½νŠΈ 및 μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 이것이 디버거가 μž‘λ™ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€. μš°λ¦¬λŠ” μ–΄λ–€ ν•¨μˆ˜λ₯Ό κ°€μ Έμ™”λŠ”μ§€ μ •ν™•νžˆ μ•Œκ³  있으며 이λ₯Ό μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ μ μ ˆν•œ (x86) opcodeλ₯Ό μ£Όμž…ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜μ˜ μ‹€ν–‰ 속도가 λŠλ €μ§€μ§€λ§Œ μ–΄μ¨Œλ“  약속이 ν•΄κ²°λ˜κΈ°λ₯Ό κΈ°λ‹€λ¦¬λŠ” κ²½μš°μ—λŠ” λ¬Έμ œκ°€ λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
이것이 LLVM 기반 C++JIT/AoTμ—μ„œ μΌμ‹œ 쀑단/디버그/재개λ₯Ό κ΅¬ν˜„ν•œ λ°©λ²•μž…λ‹ˆλ‹€.

이 λ¬Έμ œλŠ” 호슀트 바인딩 리포지토리에 μ œμΆœν•΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€...

λ‚˜λŠ” 당신이 μ›Ήμ˜ 계산 λͺ¨λΈμ„ 잘λͺ» μ΄ν•΄ν•˜κ³  μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. JavaScriptλŠ” 닀쀑 μŠ€λ ˆλ“œκ°€ μ•„λ‹ˆλ―€λ‘œ 계산을 μΌμ‹œ μ€‘λ‹¨ν•˜λ©΄ 엔진과 μ‹€μ œλ‘œ 이λ₯Ό ν˜ΈμŠ€νŒ…ν•˜λŠ” 전체 λ Œλ”λŸ¬κ°€ μ€‘λ‹¨λ©λ‹ˆλ‹€. νŽ˜μ΄μ§€κ°€ μ •μ§€λ˜κ³  λ‹€λ₯Έ μ½”λ“œλŠ” μ‹€ν–‰ν•  수 μ—†μŠ΅λ‹ˆλ‹€(λ³„λ„μ˜ μž‘μ—…μž μ œμ™Έ). ν˜„κ°€μž₯μΉ˜κ°€ 날아가도둝 ν•˜λ €λ©΄ 연속성을 κ΅¬μ²΄ν™”ν•˜κ³  λ‚˜μ€‘μ— λ³΅μ›ν•˜λŠ” 방법이 ν•„μš”ν•©λ‹ˆλ‹€. μ΄λŠ” ν˜„μž¬ 엔진이 ν•  수 μžˆλŠ” μž‘μ—…μ΄ μ•„λ‹™λ‹ˆλ‹€.

λ‚˜λŠ” 당신이 μ›Ήμ˜ 계산 λͺ¨λΈμ„ 잘λͺ» μ΄ν•΄ν•˜κ³  μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. JavaScriptλŠ” 닀쀑 μŠ€λ ˆλ“œκ°€ μ•„λ‹ˆλ―€λ‘œ 계산을 μΌμ‹œ μ€‘λ‹¨ν•˜λ©΄ 엔진과 μ‹€μ œλ‘œ 이λ₯Ό ν˜ΈμŠ€νŒ…ν•˜λŠ” 전체 λ Œλ”λŸ¬κ°€ μ€‘λ‹¨λ©λ‹ˆλ‹€. νŽ˜μ΄μ§€κ°€ μ •μ§€λ˜κ³  λ‹€λ₯Έ μ½”λ“œλŠ” μ‹€ν–‰ν•  수 μ—†μŠ΅λ‹ˆλ‹€(λ³„λ„μ˜ μž‘μ—…μž μ œμ™Έ). ν˜„κ°€μž₯μΉ˜κ°€ 날아가도둝 ν•˜λ €λ©΄ 연속성을 κ΅¬μ²΄ν™”ν•˜κ³  λ‚˜μ€‘μ— λ³΅μ›ν•˜λŠ” 방법이 ν•„μš”ν•©λ‹ˆλ‹€. μ΄λŠ” ν˜„μž¬ 엔진이 ν•  수 μžˆλŠ” μž‘μ—…μ΄ μ•„λ‹™λ‹ˆλ‹€.

μ •ν™•νžˆλŠ”, wasm은 λͺ¨λ‘ UIλ₯Ό 닀루기 λ³΄λ‹€λŠ” 계산 μž‘μ—…μ„ μœ„ν•΄ μƒμ„±λ˜μ—ˆκΈ° λ•Œλ¬Έμ— μž‘μ—…μž λ‚΄λΆ€μ—μ„œ μ‹€ν–‰λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰

κ΄€λ ¨ 문제

JimmyVV picture JimmyVV  Β·  4μ½”λ©˜νŠΈ

ghost picture ghost  Β·  7μ½”λ©˜νŠΈ

dpw picture dpw  Β·  3μ½”λ©˜νŠΈ

Thaina picture Thaina  Β·  8μ½”λ©˜νŠΈ

artem-v-shamsutdinov picture artem-v-shamsutdinov  Β·  6μ½”λ©˜νŠΈ