๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

FrontEnd

XState : ์•กํ„ฐ ๋ชจ๋ธ ๊ฐ„๋‹จํžˆ ์•Œ์•„๋ณด๊ธฐ

๋ฐ˜์‘ํ˜•

๊ณต์‹ ๋ฌธ์„œ

 

Actors | XState Docs

Actors 4.6+ ๐Ÿš€ Quick Reference The Actor model (opens new window) is a mathematical model of message-based computation that simplifies how multiple "entities" (or "actors") communicate with each other. Actors communicate by sending messages (events) to e

xstate.js.org

ํ”„๋กœ๊ทธ๋ž˜๋จธ๋กœ์„œ ์–ด๋–ค ๊ธฐ์ˆ ์„ ์ฒ˜์Œ ๋ฐฐ์šธ ๋•Œ์—๋Š” ๋ช…์„ธ๋ณด๋‹ค๋Š” ์—ญํ• , ์ฆ‰ ์šฉ๋ก€ ์œ„์ฃผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

Actor ๋ชจ๋ธ์€ Akka(Scala), Elrang์—์„œ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๊ฐœ๋…์ด๋ผ๋Š” ๊ฒƒ์€ ์•Œ๊ณ  ์žˆ์—ˆ๊ณ ,

Xstate๋กœ ์ข€ ๋” ๊นŠ์ด ์•Œ์•„๋ณผ ๊ธฐํšŒ๋ฅผ ๊ฐ€์ ธ๋ณด๋ ค ํ–ˆ์œผ๋‚˜... ์˜ˆ์‹œ๊ฐ€ ๋ณ„๋กœ ์—†์–ด์„œ ์ข€ ๋” ๋ฆฌ์„œ์น˜๋ฅผ ํ•ด๋ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค.

 

ํ•ด๋‹น ํฌ์ŠคํŠธ์—์„œ๋Š” ์ •๋ง ๊ฐ„๋‹จํ•˜๊ฒŒ๋งŒ ์•Œ์•„๋ณธ๋‹ค.

Actor์˜ ๊ทœ์น™

๋ชจ๋“  ๊ณ„์‚ฐ์€ ์•กํ„ฐ ๋‚ด๋ถ€์—์„œ ์ผ์–ด๋‚œ๋‹ค.

๊ฐ ์•กํ„ฐ๋Š” ๋ฉ”์„ธ์ง€๋กœ๋งŒ ํ†ต์‹ ํ•œ๋‹ค.

์•กํ„ฐ๋Š” ๋ฉ”์„ธ์ง€์— ์‘๋‹ตํ•˜์—ฌ ๋‹ค์Œ ํ–‰๋™์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • ์ž์‹ ์˜ ํ–‰๋™, ์ƒํƒœ๋ฅผ ๋ฐ”๊พผ๋‹ค.
  • ๋‹ค๋ฅธ ์•กํ„ฐ์—๊ฒŒ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ”๊พผ๋‹ค.
  • ์œ ํ•œ ๊ฐœ์˜ ์ฐจ์ผ๋“œ ์•กํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. 
    • ์›๋ž˜ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Ÿฌ ๋‚˜์˜จ ๊ฐœ๋…์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ : ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ชจ ์•กํ„ฐ

์ง์ ‘ ์‹คํ–‰ํ•ด๋ณด๊ธฐ

๋ถ€๋ชจ / ์ž์‹ ๋จธ์‹ ์„ ๋งŒ๋“ค๊ธฐ ์ „์—, ์‹œ์ž‘ ๋ถ€๋ถ„์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•œ๋‹ค. ์ฆ‰, ์ƒํƒœ ์ „์ด๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

const service = interpret(parentMachine, { devTools: true }).onTransition(
  (state) => {
    console.log(state.value);
  }
);

service.start();

service.send("TOGGLE");

๋” ๊ฐ„๋‹จํ•œ ์ž์‹ ๋จธ์‹ ๋ถ€ํ„ฐ ์„ค์ •ํ•œ๋‹ค

const remoteMachine = createMachine({
  id: "remote",
  initial: "offline",
  states: {
  	// ๋ถ€๋ชจ์˜ wake์— ์‘๋‹ตํ•˜์—ฌ ์ƒํƒœ๋ฅผ online์œผ๋กœ ์ „์ด
    offline: { on: { WAKE: "online" } },
    // online ์ƒํƒœ๋กœ ์ „์ดํ•œ ํ›„ 5000ms ํ›„์— ๋ถ€๋ชจ์— ๋ฉ”์„ธ์ง€(์ด๋ฒคํŠธ) ์ „๋‹ฌ.
    online: { after: { 5000: { actions: sendParent("REMOTE.ONLINE") } } }
  }
});

๋ถ€๋ชจ์™€ ์ž์‹์˜ ํ˜‘๋ ฅ ๋™์ž‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ๋ถ€๋ชจ์˜ ์ดˆ๊ธฐ ์ƒํƒœ๋Š” waiting์ด๊ณ , entry ๋‚ด์˜ ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์–ด, localOne์— ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ• ๋‹นํ•œ๋‹ค. ์ž์‹ ํ”„๋กœ์„ธ์Šค๋Š” remoteMachine์„ ํฌํ•จํ•œ๋‹ค.
  2. ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ remoteMachine์€ offline ์ƒํƒœ์ด๋‹ค. LOCAL.WAKE ์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด, ์ž์‹ ๋จธ์‹ ์— WAKE ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
  3. ์ž์‹ ํ”„๋กœ์„ธ์Šค๋Š” WAKE ์ด๋ฒคํŠธ์— ์‘๋‹ตํ•ด ์ž์‹ ์˜ ์ƒํƒœ๋ฅผ online์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒํƒœ ๋ณ€๊ฒฝ ์™„๋ฃŒ ํ›„  5์ดˆ ํ›„ ๋ถ€๋ชจ๋กœ REMOTE.ONLINE ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. 
  4. ๋ถ€๋ชจ๋Š” REMOTE.ONLINE์— ์‘๋‹ตํ•ด ์ž์‹ ์˜ ์ƒํƒœ๋ฅผ connected๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค

์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

const parentMachine = createMachine({
  id: "parent",
  initial: "waiting",
  context: { localOne: null },
  states: {
    waiting: {
     // 1. ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ€ waiting์ด๊ณ , ๋”ฐ๋ผ์„œ entry ๋‚ด์˜ ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์–ด, localOne์— ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ• ๋‹นํ•œ๋‹ค.
      entry: assign({ localOne: () => spawn(remoteMachine) }),
      on: {
        "LOCAL.WAKE": {
          actions: send({ type: "WAKE" }, { to: (context) => context.localOne })
        },
        "REMOTE.ONLINE": { target: "connected" }
      }
    },
    connected: {}
  }
});

์ด๋ ‡๊ฒŒ ์ž์‹ ํ”„๋กœ์„ธ์Šค์™€ ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ๋น„๋™๊ธฐ ํ˜‘์—… ์ƒํƒœ ๋จธ์‹ ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ  :

Spawning Child State With XState : ๊ณต์‹ ๋ฌธ์„œ ์˜ˆ์ œ

 

๋ฐ˜์‘ํ˜•