Rx? 리액티브 프로그래밍? 왜 비동기 처리로 사용될까?

Gunt·2021년 7월 27일
9


많은 사람들이 Rx라이브러리로 안드로이드 비동기처리를 사용한다. 안쓰면 뒤쳐지는 것 같아서, 다른 사람들이 사용해서, 대세라서, 많은 회사들이 사용해서...(나도 그렇게 시작했다... 반성하자)

RxJava, RxKotlin으로 안드로이드 비동기처리를 하면서 이상함(?)을 느꼈다.
왜 굳이 Rx를 사용하는걸까?
계속 의문이 생겼다.
이게 비동기 처리에 굳이 사용되어야 하는건가? 데이터를 스트림으로 처리하는게 왜 좋은거지?

의문을 해결하기 위해, 본질을 모르고 개발하고 싶지 않아 공부하며 글을 작성한다.

리액티브 프로그래밍? 반응형 프로그래밍? 그게 뭔데?
: 아~~ 데이터를 스트림형식으로 받아서 처리하는걸 반응형이라고 하는구나~ <-- (완전 겉핥기, 특징과 본질을 아~주 정확하게 오해한 좋은 예)

제대로 이해해보자.

먼저 Rx부터 보자.

Rx 왜 나왔니?

Rx란?

: 비동기와 이벤트 기반 프로그램을 잘 작성하기 위해 필요한 observable sequence 라이브러리
비동기 처리 해법으로 탄생 = (Observable + LINQ + Scheduler)
명료하게 설명한 듯 하지만 감이 잘 오지 않았다.

Rx는 어디에서 왔을까(역사)

: 비동기 프로그래밍 문제를 해결하기 위해 만들어짐 (비동기, 데이터 동기화의 중요성이 증가됨에 따라 점차 각광)
비동기처리를 위해 만들어진만큼 비동기에 특화되어있겠다라는 생각을 할 수 있다.

소프트웨어 환경은 과거와 많이 달라짐
-> 인터넷이 발달하면서 트래픽이 이전에 비해 많이 달라짐
-> 동시접속자 수 늘어남
-> 무어의 법칙 깨짐
-> 사용자의 요구사항은 늘어나고 더 빠른 반응속도를 기대함
-> 소프트웨어는 더 복잡해졌고, 안정성은 더 중요한 문제가 됨
-> 회복탄력성과 유연성을 갖도록 시스템을 설계해야한다! <-- 달성 방법으로 Message Driven이 탄생


리액티브 프로그래밍

: 변화의 전파와 데이터 흐름과 관련된 선언적 프로그래밍 패러다임
어렵네? 이름도 추상적인데 정의도 어려워...

외부에서 들어오는 자극에 반응*하는 구조를 만드는 것을 목적으로 프로그래밍을 함
반응*: 밖에서 안으로, 그리고 수동적으로
   - 프로그램이 외부와 상호작용하는 기존의 방식을 거꾸로 뒤집어서 수동적 반응을 획득하는 일


외부 환경에 대한 결과를 반환하는 과정을 두 가지 시나리오로 설명할 수 있다.

pull, push Scenario

pull 시나리오 : 프로그램이 외부환경의 명령에 의해서 원하는 결과를 획득한다.
이경우 프로그램이 직접 제어의 흐름을 통제한다. (명령형 - 우리가 일반적으로 자주 사용하는 코드스타일)
(ex. Iterator)
push 시나리오 : 환경이 프로그램 안으로 요청을 밀어넣는다. 요청이란 메세지, 데이터 상태 등등.
(ex. Observable)

pull 시나리오 : 비동기 request 던지고 response를 기다렸다가 callback으로 받아서 처리
vs
push 시나리오 : 비동기 request를 던지고, 외부데이터 스트림에 대한 subscribe형식으로 유입에 반응하도록 처리

차이 - 외부 환경에 명령을 하고 응답이 오기까지 기다리는것이 pull,
기다리지 않는 것이 push <-- 그 순간에 반응하는 것

따라서 push 시나리오는 제어의 흐름을 직접 통제하지 않기 때문에 비동기처리에 유리하다.

그럼 이 두 가지(Iterator, Observable)는 완벽히 다른 것인가?
-> 이벤트를 여러번 호출하면 연속하는 데이터를 주입할 수 있다. -> 두 가지의 본질은 같다.(* 다만 데이터가 흐르는 방향이 다를 뿐)
* 데이터의 방향이 다르다는 것이 늘 추상적으로 느껴졌고 암기의 개념처럼 느껴졌다. 그러나 알고보면 이것만큼 반응형을 표현할 방법이 없다...

Rx는 Observer패턴에서 좀 더 진화된 인터페이스인 Observable을 제공한다.
Iterator로 사용하는 모든 것들을 Observable로 표현할 수 있다. 단,데이터가 흐르는 방향만 반대로! <-- 이게 바로 리액티브 프로그래밍이 지향하는 수동적 방향성이다!!


정리

  1. 비동기 처리를 Rx로 해야하는 것이 아니라, 비동기 처리 개념을 반응이라는 다른 시선으로 바라보고 해결하려 했다는 것
  2. callback을 기다리는 기존 pull시나리오 개념이 아닌, 외부 데이터 유입에 반응하여 더 자연스러운 비동기 처리가 가능하도록 push시나리오로 만드는 것
  3. 반응할 유입 데이터를 stream으로 받게되고 그 데이터를 의도한 모양의 데이터로 변형시켜 사용할 수 있다는 장점은 덤!

다른 특징들과 장점들이 더 있겠지만, Rx가 가진 패러다임을 이해하는 데에 꽤 중요한 개념들을 알게되었다. 앞으로의 Rx사용은 단순한 적용보다 Rx가 가진 본질적인 의도에 맞게 사용이 가능해질 것 같다.



다만...

아직 Rx에 대해 궁금한 점이 남아있다.

풀리지 않은 궁금증

  1. Rx라이브러리의 Observable + LINQ + Scheduler의 각 요소들의 동작 원리
  2. Rx가 스트림으로 데이터를 처리한다면 그 데이터가 메모리에 적재되는 공간은 어디이며 어떻게 사용되고 소멸되는가

남은 궁금증은 계속 탐구하면서 다음 글로 남겨봐야겠다.


참고 자료: https://www.youtube.com/watch?v=3FKlYO4okts

profile
기술에 생각 더하기

4개의 댓글

comment-user-thumbnail
2021년 7월 27일

오졌따

답글 달기
comment-user-thumbnail
2021년 7월 27일

Rx가 스트림으로 데이터를 처리한다면 그 데이터가 메모리에 적재되는 공간은 어디이며 어떻게 사용되고 소멸되는가?

Rx 1도 모르지만 대충 뇌피셜로 써보자면..
스트림이라는 것은 일련의 데이터 덩어리를 잘게 쪼개어 보내는 것이라는 전제를 깔아봅니다.
데이터를 받는 쪽에서 이 스트림이 serialized 되어 하나의 객체가 될 것이라 보면
우리가 일반적으로 obj = new Object() 를 사용하는 것과 크게 다르지 않을 것이라 생각함니다.
결론은 JVM 영역에 알아서 데이터의 크기만큼 적재 되지 않을까.

2개의 답글