자기개발/개발이야기

함수형 언어에서 state를 관리하는 법

(Elixir 특징상, 이 글에서의 Process는 Erlang Process입니다.)

서론

함수형 언어의 특징으로는 Pure Function이 있다.
하지만 프로그램을 짜면 state 관리는 필요하다.
따라서 pure function에 state를 넘겨주는 방식으로 관련 처리를 한다. (elixir에서는 그랬다.)

그런데 `그럼 함수형 언어에서 state 관리는 어떻게 해?' 라는 질문을 친구한테 들었다.
질문 자체가 포괄적이긴 하다. 그냥 얼랭 프로세스에서 하나 들고있고, 그걸 쓴다 하기에는 친구가 납득하지 못한 느낌이었고, 나도 납득할만한 설명을 못했다고 생각했다.

납득할 만한 설명을 하려고, 인터넷을 좀 찾아봤다.
어느정도 납득할만한 설명을 봐서, 정리하고자 이 글을 쓴다.
(https://www.quora.com/How-do-you-handle-state-in-functional-programming-Do-you-have-it-in-a-huge-global-variable-like
)

Elixir에서는 state를 어떻게 관리하나?

  • map(structure)로 관리. 이것을 pure function을 통해 계속 변경시켜나간다.
  • 계속 도는 process가 있음. 이 프로세스는 자신을 계속 호출함. 그 호출 루프에는 새로운 state가 파라메터로 주어짐.
  • ets와 dets 모듈을 사용해서 아에 따로 관리함
  • RDBMS나 NoSQL을 찾아봄

Phoenix에서의 접근법 (pure function으로 변경)

  • web request가 오면, Conn Structure가 생성되고, 리퀘스트에 관한 정보로 채워진다.
    • 이것이 state에 해당된다.
    • 딴이야기 : 채워진다 - populated 라는 표현을 쓰더라.
  • 각종 layer를 거치며 이 Conn 이 변경되어간다.
    • Routing, Json Encoding 등등...

Long Running Process 접근법

  • 한개의 State를 저장하는 process를 둔다
  • 그 process를 통해 state의 갱신을 이룬다.
    • 갱신도 그 process에 state의 갱신을 요청하는 식으로 한다.
    • 값이 필요하면 그 process에 state의 값을 요청한다.

앱이 재시작되거나 예외에 부딪히면?

  • 외부에 값을 저장할 필요가 있다.

  • 이때 쓰는 것이 RDB와 NoSQL, DISK 등의 모듈이다.

    실제는 어떻게 쓰이나
  • 이런 state를 저장하는 Process들이 엄청 많이 떠있다

    • erlang process는 비용이 매우 낮기에, 이렇게 하는 방식이 효율적이다.
    • 어떠한 단위 하나당 하나의 process를 생성하는게 보통이다.
  • 하나의 큰 process보다는 잘게 쪼개서 쓴다.

    • 비용이 비싼 OS threads에는 하기 힘든, actor모델의 장점을 살리는 방식이다.