본문 바로가기

유니티 개발 정보/프로그래밍

Reactive Exntenstion(Rx) - 1

Reactive Extensions(Rx)란 무엇인가?[각주:1]


Reactive Extensions (이하 Rx)는 observable sequence[각주:2] LINQ형식의 쿼리문, 비동기 이벤트-기반 프로그래밍으로 구성 라이브러리다.

Data sequences는 파일, 웹 서비스, 웹 서비스 요청, 시스템 알림 또는 유저 입력같은 일련의 이벤트들 처럼 많은 형식을 취할 수 있다. 

Rx는 위에서 언급된 모든 데이터들을 observable sequence로 나타낼 수 있다.

새로운 데이터가 도착할 때 비동기적으로 알림을 받기 위해, 어플리케이션들은 observable sequence들을 구독한다.



Pulling vs. Pushing Data


인터랙티브 프로그래밍에서, 어플리케이션은 순서대로 나열된 데이터에서, 활발히 데이터를 얻어온다. 이런 행동은 IEnumerable<T> 혹은 IEnumerator<T>의 반복자 패턴로 표현된다
IEnumerable<T> 인터페이스는 이들 집합들을 순회하기위해 IEnumerator<T>를 반환하는 GetEnumerator()를 노출한다.

IEnumerator<T>은 current를 통해 현재 값을 얻을 수 있고, MoveNext 메소드를 통해 더 많은 항목들이 존재하는지 알 수 있도록 해준다.


어플리케이션은 데이터 검색 프로세스에있어 적극적이다. 게다가 enumerator를 얻기위해 GetEnumerator를 호출하는데, GetEnumerator는 MoveNext를 호출하여 검색의 흐름을 제어한다. enumeration 패턴은 동기적인데, 이는 데이터 소스를 가져오는 동안 어플리케이션이 블럭된다는 것을 의미한다. 이런 패턴은 책을 빌리기 위해 도서관을 방문하는 것과 비슷하다. 책을 다 읽은 후에 다른 책을 빌리기 위해 다시 도서관을 방문해야 한다.


반면에, 반응형 프로그래밍에서는 데이터 스트림(Rx에서는 observable sequence라고 불리는)을 구독함으로써 더 많은 정보를 얻고, 모든 데이터 소스로부터 모든 변경사항을 받는다. 어플리케이션은 observable 데이터를 구독하는 것이외에는 데이터 검색 프로세스에서 수동적이며, 적극적으로 데이터를 받아오지 않고, 단지 푸쉬되는 데이터에 한해서만 받응한다. 스트림이 더 이상 데이터를 제공하지 않거나, 에러가 발생했을 때, 데이터는 구독자에게 이 소식을 알린다. 이런 방식은, 데이터를 업데이트하는데 있어서 블럭되지 않는다.


이 푸쉬 방법은 Reactive Extension을 사용한다. 이는 책모임에 가입해서 자신이 좋아하는 장르를 등록하면, 책모임에서 자신이 등록한 책들과 출판된 책들을 매칭해서 나에게 전달해주는 것 방식과 유사하다. 이는 원하는 책을 얻기위해서 줄을 서야할 필요가 없다.

이 푸시 방법을 사용하는 것은 많은 상황에서 유용한데, UI 기반 환경에서 UI 쓰레드가 특정 이벤트를 기다리는데 블럭당할 필요가 없어지기 때문이다. Rx를 사용함으로써, 어플리케이션을 좀 더 반응성있게 만들 수 있다.


Rx에 의해 구현된 push 모델은 IObservable<T> IObserver<T>의 observable 패턴으로 표현된다.
IObservable 인터페이스는 IEnumerable<T>와 비슷한 쌍을 이루는 인터페이스다. 데이터를 추출하고, 데이터에 관심을 가지는 IObserver<T> 구현 리스트를 유지한다. IObservable은 모든 observer들에게 모든 상태 변화를 알린다. 
구독을 통해 관심있는 데이터에 등록하기위해서, IObserver를 매개변수로 받고 IDisposable을 반환하는 IObservable의 Subscribe메소드를 사용한다. 구독을 추적하고, 처분할 수 있도록 도와준다. 게다가 Rx’s의 Observable Sequence에 대한 구현은 .NET 이벤트, APM-기반(“IAsyncResult”) 계산, Task<T>-기반 계산, 비동기 작업흐름같은 푸쉬-기반 시퀀스에 대해, 복잡한 이벤트 처리 쿼리가 가능하다.

1
2
3
4
public interface IObservable<T>
{        
    IDisposable Subscribe(IObserver<T> observer);
}
cs

1
2
3
4
5
6
public interface IObserver<T>
{
    void OnCompleted();
    void OnError(Exception error);
    void OnNext(T value);
}
cs




  1. 본문은 MSDN의 Reactive Extensions를 번역한 글입니다. [본문으로]
  2. 구독할 수 있는 데이터 스트림(흐름)이다. [본문으로]