[Esper Manual 4.10.0 번역] 섹션 14.3 관리 인터페이스

14.3.1 문장 생성

이벤트 패턴 식과 EPL 문장을 관리 인터페이스인 EPAdministrator를 통해서 생성한다.

아래 코드조각은 Esper 엔진을 얻어와서 이벤트 패턴과 EPL 문장을 생성한다.

이벤트 패턴 식은 EPL 문장 안에 포함 될 수 있다는 점을 주목해야 한다. 이 내용은 섹션 5.4.2 “패턴 기반 이벤트 스트림”에서 자세하게 다룬다.

EPAdministrator의 create 메서드는 오버로드되며 선택적으로 문장 이름이 엔진에 전달되는 것을 허용한다. 문장 이름은 나중에 엔진으로부터 이름을 가지고 문장을 얻을 수 있는데 유용하게 활용될 수 있다. 엔진은 문장 이름이 문장 생성시 제공되는 것이 아니면 문장 이름을 할당한다.

createPattern과 createEPL 메서드는 EPStatement 인스턴스를 반환하다. 문장은 자동적으로 생성시에 시작되어 활성화된다. 문장은 또한 다음 코드조각과 같이 stop, start 메서드를 통해서 정지 및 재시작 될 수 있다.

EPAdministrator의 create 메서드는 또한 유저 객체를 수용한다. 유저 객체는 문장의 생성시점에 문장과 연관이 되는 하나의 이름 없는 필드로 모든 문장에 저장된다. 당신의 애플리케이션은 이 필드 안에 임의의 객체를 넣어둔다. EPStatement의 getUserObject를 사용하여 문장의 유저 객체를 얻을 수 있고 StatementAwareUpdateListener를 리스너로 사용한다.

당신의 애플리케이션은 새로운 문장을 생성하거나 스레드를 통하거나 또는 리스너나 구독자 코드 안에서 기존 문장을  중지시키고 제거할수도 있다. POJO 이벤트를 사용한다면, 당신의 애플리케이션은 동일한 이벤트가 현재 문장에 의해서 처리 중일 때는 이벤트 객체 그 자체 안에서는 문장을 생성하거나 관리할 수 없다.

14.3.2 문장 결과를 받기

Esper는 문장의 결과를 받는데 3가지 선택사항을 제공한다. 당신의 애플리케이션은 3가지 메커니즘을 각기 사용하거나 각 문장에 대해서 어느 조합으로도 사용할 수 있다. 선택사항은 아래와 같다.

  1. 리스너 콜백 / addListener와 removeListener / 당신의 애플리케이션은 UpdateListener 또는 StatementAwareUpdateListener 인터페이스의 구현을 문장에 제공한다. 리스너는 문장의 결과를 담고 있는 EventBean 객체를 받게 된다. 엔진은 연속적으로 결과가 발생하자마자 모든 리스너와 지정했다면 ouput율을 제한하는 절에 결과를 알려준다.
  2. 구독자 객체(Subscriber Object) / setSubscriber / 당신자의 애플리케이션은  문장 결과를 받기 위해서 메서드를 공개하는 POJO를 제공한다.엔진은 연속적으로 결과가 발생하자마자 모든 리스너와 지정했다면 ouput율을 제한하는 절에 결과를 알려준다. 이것은 엔진이 확실하게 타입이 정해진 결과를 직접 애플리케이션에 전달하기 때문에 문장의 결과를 받는 가장 빠른 방법이다. 문장 당 최대 1개의 구독자 객체가 등록 가능하다. 만약 1개 이상의 리스너를 사용하려면 대신 리스너 콜백을 사용하는 것이 좋다. 구독자 객체는 타입 변환 없이 새로운 이벤트의 직접적인 전달을 보장하기 때문에 확실한 타입 지원이 필요하다. 이러한 최적화는 문장당 구독자 객체가 오직 0개 이거나 1개 이기 때문에 가능하다.
  3. Pull API / safeIterator와 iterator / 당신의 애플리케이션은 문장에게 결과를 요청하고 java.util.Iterator<EventBean>을 통해서 이벤트의 집합을 받는다. 이 방법은 실시간으로 새로운 결과를 연속적으로 알릴 필요가 없을 경우에 유용하다.

당신의 애플리케이션은 1개 이상의 리스너를 부착하거나, 0 또는 1개의 구독자를 부착할수도 있고 거기다 동일한 문장에 Pull API를 사용할 수도 있다. iterator, 구독자의 사용이나 리스너의 단독 사용, 또는 조합된 형태 모두 문장의 결과를 받는데 사용 가능하다.

최고의 전달 성능은 일반적으로 리스너를 붙이는 것보다 구독자를 붙이는 것을 통해서 달성할 수 있다. 엔진은 문장에 부착된 리스너와 구독자를 인식한다. 엔진은 문장의 오버헤드를 줄이기 위해 내부적으로 이러한 정보를 사용한다. 예를 들면 당신의 문장이 리스너나 구독자가 부착하지 않았다면, 엔진은 연속적으로 결과를 생성하여 전달할 필요가 없기 때문이다.

만약 당신의 애플리케이션이 구독자와 하나 이상의 리스너를 모두 사용한다면 구독자는 어느 리스너보다도 먼저 결과를 받을 것이다.

만약 당신의 애플리케이션이 하나 이상의 리스너를 부착했다면 UpdateListener 리스너들은 문장에 추가된 순서로 먼저 결과를 받고 StatementAwareUpdateListener 리스너들은 다음으로 문장에 추가된 순서대로 결과를 받는다. 당신의 애플리케이션에서 리스너 사이의 전달 순서를 변경하기 위해서 실행 중에 리스너를 추가 및 제거할 수도 있다. 만약 당신이 outbound 쓰레딩을 설정했다면, 연산이나 이벤트 전달 쓰레드 대신에 outbound 쓰레드 풀에서 하나의 쓰레드가 결과를 구독자나 리스너에 결과를 전달한다.

만약 outbound 쓰레드가 켜져 있다면, 우리는 리스너에 전달된 이벤트의 순서를 보존하는 엔진 설정을 끌것을 제안하며 이는 섹션 15.4.10.1 “리스너에 전달된 이벤트의 순서 보존”에서 설명한다. 만약 outbound 쓰레드가 켜져 있으면 문장의 실행은  구독자나 리스너가 너무 많은 시간을 차지하는 것에 대비해 설정된 시간에 따라 차단되지 않는다.

14.3.3 구독자 객체를 설정하기

구독자 객체(Subscriber object)는 자바 객체 쿼리의 결과를 직접 묶는 것을 말한다.   POJO 타입의 객체는 메서드 호출을 통해서 문장의 결과를 받는다. 구독자 클래스는 인터페이스를 구현하거나 슈퍼클래스를 상속받을 필요가 없다. 오직 하나의 구독자 객체는 하나의 문장을 위해 설정될 수 있다.

구독자 객체는 리스너보다 몇가지 이점을 보유한다. 첫 번째로, 잠재적인 성능 장점을 제공한다. 쿼리의 결과가 자바 가상 머신의 메서드 호출을 통해 직접 당신의 메서드로 전달되며 Event Bean과 같은 중간 전환 과정을 거치지 않는다. 둘째로 구독자는 강하게 결합된 매개변수를 받기 때문에 구독자 코드는 간단하게 구현 가능하다.

이 챕터에서는 당신의 구독자 클래스를 통해 제공되는 메서드의 요구사항에 대해서 설명한다.

엔진은 두 가지 방법을 통해서 결과를 제공한다.

  1. insert 스트림 안에 있는 각 이벤트는 메서드를 호출하고 remove 스트림 안에 있는 이벤트도 다른 메서드를 호출한다. 이 방법을 row-by-row 전달이라고 한다.
  2. insert와 remove 스트림의 모든 행을 전달하는 단일한 메서드 호출이 있으며 이를 multi-row 전달이라고 한다.

14.3.3.1 Row-By-Row 전달

당신의 구독자 클래스는 insert 스트림의 이벤트를 받가 위해서 반드시 update라는 이름의 메서드를 제공하여 한다. 매개변수의 개수와 타입은 update 메서드에서 선언되어 select 절에 기술된 동일한 순서대로 열의 개수와 타입과 반드시 일치해야한다.

예를 들면, 만약 당신의 문장이 다음과 같다고 가정해보자:

그렇다면 당신의 구독자 클래스의 update 메서드는 다음과 같을 것이다

update 메서드에서 선언한 각 메서드의 매개변수는 반드시select 절의 나열된 순서 대로 각각의 열의 타입으로부터 반드시 할당이 가능해야 한다. 할당의 규칙은 다음과 같다

  • 타입의 확장은 자바 기준을 따른다. 예를 들면 당신의 select 절이 정수 값을 선택한다고 하면 동일한 열에 해당하는 메서드의 매개변수는 int, long, float 이나 double (혹은 이와 동등하게 객체로 박싱되는 타입)의 타입이 될 수 있다.
  • 자동 박싱과 언박싱[역자주: 래퍼 클래스의 따른 형변환]은 자바 기준을 따른다. 예를 들면 만약 당신의 select절이 java.lang.Integer 값을 선택한다면, 동일한 열에 속한 메서드의 매개변수는 int 타입이 될 수 있다. 만약 당신의 select 절의 열이 null 값을 발생시키면, 실행 중에 null 값을 언박싱하는 과정에서 예와가 발생할 수 있다.
  • 인터페이스와 슈퍼클래스는 할당을 위한 테스트로서 의미가 있다.따라서 java.lang.Object는 select 절의 어떤 열의 타입도 받아서 사용할 수 있다.

당신의 구독자 클래스가 복수의 update 메서드 footprint를 갖는 경우를 보자. 이 때 엔진은 결과 타입과 메서드의 매개변수의 타입을 비교하여 가장 일치하는 footprint를 선택한다. 엔진은 정확하게 타입이 일치하는 경우를 최우선으로 선호하며, 다음으로 박싱이나 언박싱을 요구하는 메서드, 타입의 확장을 요구하는 메서드, 그리고 마지막으로 허용 가능한 타입의 메서드 순으로 선호한다.

14.3.3.1.1. 와일드카드

만약 당신의 select 절이 하나 이상의 와일드카드(*)를 보유하고 있다면, 동등한 매개변수의 타입은 선택된 스트림의 기본이 되는 이벤트 타입이 된다.

예를 들면, 당신의 문장이 다음과 같을 수 있다.

그러면 당신의 구독자 클래스의 update 메서드는 다음과 같다.

조인 연산의 경우 와일드카드는 from 절에서 나타난 스트림의 순서에 따라 각 스트림의 기본 이벤트 타입을 확장 된다. 다음 문장은 조인의 예이다.

그러면 당신의 구독자의 update 메서드는 다음과 같이 된다.

스트림의 와일드카드 문법과 스트림의 이름 자체는 다음과 같이 사용가능하다.

일치하는 udpate 메서드는 다음과 같다.

14.3.3.1.2. Map과 객체 배열로 행 전달

다른 방법으로, 당신의 update 메서드는 각 행의 표현 방식으로 java.util.Map을 간편하게 선택하여 수용할수도 있다. select 절의 각 열은 결과 Map의 요소로 생성된다. Map의 키는 공급되는 열의 이름이 되거나 이름 없는 열에서는 문자열 표현 자체가 된다.

Map 전달을 위한 update 메서드는 다음과 같다.

엔진은 또한 select절의 전송을 객체 배열로도 지원한다. 객체 배열의 각 요소는 select 절의 각 열을 표현한다. update 메서드는 다음과 같이 표현된다.

14.3.3.1.3. Remove 스트림 이벤트의 전달

당신의 구독자는 만약 updateRStream이란는 메서드를 제공한다면 remove 스트림 이벤트를 받을 수 있다. 이 메서드는 update메서드와 동일하게 똑같은 매개변수의 개수와 타입을 받는다.

문장의 예는 다음과 같다.

그러면 update 메서드와 updateRStream 메서드는 다음과 같이 될 수 있다.

14.3.3.1.4. 시작과 끝의 알림 전달

만약 당신의 구독자가 이벤트의 시작과 끝의 노티피케이션을 요구한다면 updateStart와 updateEnd 메서드를 통해서 노출시킬 수 있다.

updateStart 메서드는 insert 스트림의 이벤트 개수와 전달되는 remove 스트림을 알려주는 두 개의 정수 매개변수를 가져야 한다. 엔진은 updateStart 메서드를 즉시 호출하여 이벤트를 update와  updateRStream메서드에 전달하는 것보다 앞선다.

updateEnd 메서드는 어떠한 매개변수도 필요하지 않다. 엔진은 update와 updateRStream메서드로 이벤트를 전달한 후에 바로 호출된다.

전달 메서드의 예는 다음과 같다.

14.3.3.2 Multi-Row 전달

row-by-row 전달을 대신해서 당신의 구독자는 insert와 remove 스트림에 있는 모든 이벤트를 단일한 메서드 호출을 통해서 전달 받을 수 있다. 이 방법은 주어진 입력 이벤트나 시간 변동에 따른 EPL이 복수의 결과 행을 전달할 때 적용한다. 예를 들면 동일하게 들어오는 이벤트에서 복수의 패턴 매칭이 일어날 때, 조인이 복수의 결과 행에 발생할 때나 출력률을 제한하지 않을 때 등이다.

이벤트의 전달은  앞선 14.3.3.1.2 섹션의 Map과 객체 배열로 행 전달의 구조를 따른다.  구독자 클래스는 반드시 다음의 메서드 가운데 하나를 제공해야 한다.

  • update(Object[][] insertStream, Object[][] removeStream): 각 객체 배열의 첫 번째 차원은 이벤트의 행을 의미하고 두번째 차원은 문장의 select절의 열 순서에 일치한다.
  • update(Map[] insertStream, Map[], removeStream): 각 Map은 하나의 이벤트를 표현하고 Map의 요소는 문장의 select 절의 열을 나타낸다.

14.3.3.2.1. 와일드카드

만약 당신의 select 절이 하나 이상의 와일드카드를 포함한다면, 구독자 객체는 아마 직접 기본 이벤트의 배열을 받을 것이다. 이 경우에는 구독자 클래스는 update(Underlying[] insertStream, Underlying[] removeStream) 같은 메서드를 제공해야 하며 “Underlying”은 기본 이벤트의 클래스를 나타낸다.

예를 들면, 당신의 문장이 다음과 같다면

당신의 구독자 클래스는 다음과 같은 메서드를 포함해야 한다.

14.3.3.3.  매개변수가 없는 Update 메서드

당신의 구독자 객체가 문장으로부터 아무런 데이터를 받기를 원하지 않는 경우에는 다음의 지시사항을 따르면 된다.

당신의 EPL 문장은 반드시 하나의 null 값을 선택해야 한다.

예를 들면, 당신의 문장은 다음과 같을 수 있다.

당신의 구독자 클래스는 다음의 메서드를 포함한다.