입력 어댑터 및 출력 어댑터 만들기

 

참고


입력 및 출력 어댑터는 이전 버전의 StreamInsight에서 도입되었습니다. 현재 개발 모델로 대체되었지만 레거시 코드를 유지 관리하는 개발자들은 계속 사용할 수 있습니다. 현재 개발 모델에 대한 자세한 내용은 개발자 가이드(StreamInsight)를 참조하십시오.

이 항목에서는 StreamInsight 플랫폼을 사용하는 CEP(복합 이벤트 처리) 응용 프로그램용 입력 및 출력 어댑터를 만드는 데 필요한 일반적인 정보를 제공합니다. 어댑터는 이벤트를 StreamInsight 서버로 또는 해당 서버 외부로 전달하는 소프트웨어 변환기입니다.

이벤트 흐름 및 제어 이해

어댑터를 만들 때는 StreamInsight 서버를 통한 이벤트 흐름과 입력 및 출력 어댑터가 이 흐름을 제어하는 방식을 이해하는 것이 중요합니다. 다음 그림에 나와 있는 것처럼 원본에서 고정 쿼리를 거쳐 싱크로 이동하는 이벤트의 흐름은 단방향으로 이루어집니다. 즉, 입력 어댑터가 이벤트를 원본에서 읽어 쿼리로 전달하면 입력 이벤트 또는 입력 이벤트를 처리하면 생성되는 새 이벤트가 쿼리의 각 연산자 간에 순서대로 밀어넣기됩니다. 쿼리가 처리된 이벤트를 출력 어댑터로 전달하면 출력 어댑터에서 이벤트를 싱크로 전달합니다. 아래 그림에서는 StreamInsight 쿼리가 두 입력 어댑터 인스턴스(a1 및 a2)와 출력 어댑터 인스턴스(a4)에 바인딩되는 시나리오를 보여 줍니다.

EventFlow

이벤트 흐름은 원본에서 싱크로의 단방향으로 진행되는 반면, 구성 요소 간의 일부 상호 작용 지점에서 수행되는 이벤트 검색 및 전송의 흐름 및 실행 제어는 양방향으로 진행될 수 있습니다. 이러한 상호 작용 지점은 그림에서 READ, ENQUEUE, DEQUEUE, WRITE로 표시되어 있습니다.

입력 어댑터 구현에서는 파일, 데이터베이스 등의 원본 장치와 관련된 액세스 메커니즘을 사용하여 READ 작업을 수행해야 하며 어댑터 API를 사용하여 ENQUEUE 작업을 수행해야 합니다. 마찬가지로 출력 어댑터 구현에서는 싱크 장치와 관련된 액세스 메커니즘을 사용하여 WRITE 작업을 수행해야 하며 어댑터 API를 사용하여 DEQUEUE 작업을 수행해야 합니다. ENQUEUE 및 DEQUEUE 작업은 이 항목 뒷부분에서 설명하는 어댑터 상태 전환 다이어그램으로 지정되는 디자인 패턴에 따라 구현해야 합니다.

이벤트 흐름 제어 측면에서 볼 때 이벤트는 공급자에서 소비자로 밀어넣기되거나(왼쪽에서 오른쪽 방향의 블록 화살표로 표시됨) 끌어오기된다고(갈고리 모양 화살표로 표시됨) 볼 수 있습니다. READ 및 WRITE 상호 작용 지점에서 어댑터 구현은 이벤트 흐름 제어를 위해 밀어넣기 또는 끌어오기 방식을 적용할 수 있습니다. 이 상호 작용에 대해 고려해야 할 몇 가지 요인으로는 원본이나 싱크에서 가능한 이벤트 속도, 어댑터가 원본이나 싱크를 스로틀하는 기능, 구현 가능한 버퍼링 기능 등이 있습니다.

대기 시간이 매우 짧을 때 이벤트를 내보내며 스로틀하기가 어려운 원본 장치의 경우에는 보통 원본 장치가 이벤트를 어댑터로 밀어넣는 어댑터를 구현합니다. 이러한 장치의 예로는 센서(컴퓨터 구동 이벤트), 주식 종목 표시 장비, 네트워크 포트 등이 있습니다. 지연이 긴 장치(파일, 데이터베이스)의 경우에는 어댑터가 원본에서 데이터를 끌어오는 구현을 고려하십시오. 마찬가지로 출력 측에서는 매우 높은 처리량으로 이벤트를 허용할 수 있는 출력 어댑터를 장치에 대해 구현해 이벤트를 장치로 밀어넣을 수 있습니다. 속도가 느린 출력 장치의 경우에는 장치가 이벤트를 사용할 준비가 되면 항상 어댑터를 폴링하는 방식을 적용할 수 있습니다.

ENQUEUE 상호 작용 지점에서 StreamInsight 서버는 밀어넣기 모델을 지원합니다. 즉, 어댑터 디자인 패턴에서는 임의의 지정 시간에 엔진이 사용할 수 있는 최대 이벤트를 큐에 넣을 수 있습니다. DEQUEUE 상호 작용 지점에서 StreamInsight 서버는 끌어오기 모델을 지원합니다. 즉, 어댑터 디자인 패턴에서는 엔진이 제공 가능한 최고 속도로 서버의 이벤트를 끌어와야 합니다.

이러한 사실을 고려하면 StreamInsight 서버의 처리량 정책은 매우 단순합니다. 차단 작업이 없는 단순한 통과 쿼리를 가정할 때 StreamInsight 서버가 ENQUEUE 상호 작용 지점에서 입력 어댑터의 이벤트를 사용할 수 있는 속도를 제한하는 요인은 출력 어댑터가 DEQUEUE 상호 작용 지점에서 서버의 이벤트를 사용할 수 있는 속도뿐입니다. StreamInsight 서버가 ENQUEUE 중에 입력 어댑터로 이벤트를 다시 밀어넣는 범위는 쿼리가 출력을 해제할 수 있는 속도와 출력 어댑터가 이 출력을 사용할 수 있는 속도에 따라 결정됩니다. StreamInsight에서는 이러한 각 상호 작용 지점에서 이벤트 속도를 측정하는 데 사용할 수 있는 광범위한 진단 보기 집합이 제공됩니다. 자세한 내용은 StreamInsight 서버 및 쿼리 모니터링을 참조하십시오.

어댑터 개발 태스크

어댑터를 개발할 때는 다음 검사 목록을 사용합니다.

  • 필요한 어댑터 유형(입력/출력)을 결정합니다.

    입력 어댑터는 들어오는 이벤트를 제공된 형식으로 읽은 다음 이 데이터를 StreamInsight 서버에서 사용할 수 있는 형식으로 변환합니다.

    출력 어댑터는 StreamInsight 서버에서 처리한 이벤트를 받아 출력 장치에 필요한 형식으로 변환한 다음 해당 데이터를 장치로 내보냅니다.

  • 이벤트 유형을 결정합니다.

    입력 어댑터의 경우에는 원본에서 제공하는 이벤트 페이로드를 설명하는 이벤트 유형을 정의합니다. 출력 어댑터의 경우에는 싱크에서 사용하는 이벤트 페이로드를 설명하는 이벤트 유형을 지정합니다. 이벤트 페이로드에 대한 자세한 내용은 StreamInsight 서버 개념을 참조하십시오.

    항상 고정 페이로드 형식(필드 수 및 해당 유형이 사전에 확인됨)의 이벤트를 생성하거나 사용하는 형식화된 어댑터를 원본 또는 싱크에 대해 지정하고 빌드할 수 있습니다. 형식화된 어댑터의 가장 큰 장점은 StreamInsight 서버의 큐에 넣을 이벤트를 만드는 구현이 비교적 쉽다는 점입니다. 필드 형식을 이미 알고 있으므로 Visual Studio의 IntelliSense 또는 기타 통합 개발 환경의 해당 기능을 사용하여 필드를 채울 수 있습니다.

    원본 또는 싱크에서 서로 다른 페이로드 형식을 생성하거나 사용하는 경우에는 형식화되지 않은 어댑터를 지정하고 빌드할 수 있습니다. 형식화되지 않은 어댑터의 가장 큰 장점은 어댑터 구현을 특정 이벤트 유형에 연결하는 대신 쿼리 바인딩 시에 이벤트 유형을 지정하는 유연한 기능을 제공한다는 점입니다. 그러나 형식화된 어댑터에 비해 형식화되지 않은 어댑터의 구현은 보다 복잡합니다. 형식화되지 않은 입력 어댑터는 쿼리 바인딩 중에 제공되는 구성 매개 변수에서 각 필드의 유형을 확인하고 필드를 한 번에 하나씩 채운 다음 이벤트를 큐에 넣을 수 있도록 작성해야 합니다. 마찬가지로 형식화되지 않은 출력 어댑터는 출력 시에 제공된 구성 정보를 기반으로 큐에서 제거된 이벤트에서 쿼리 처리 결과를 검색할 수 있어야 합니다.

    형식화 여부에 관계없이 쿼리에 바인딩되는 어댑터 인스턴스는 항상 특정 단일 유형의 페이로드를 포함하는 이벤트를 내보냅니다. 자세한 내용은 이벤트 구조를 참조하십시오.

  • 이벤트 모델을 결정합니다.

    입력 이벤트와 출력 이벤트의 이벤트 모델을 결정합니다. StreamInsight에서는 지점, 간격, 가장자리 이벤트 모델이 지원됩니다. 원본이 고정된 이벤트 모델의 이벤트를 제공하는 경우에는 해당 이벤트 모델용으로만 입력 어댑터를 디자인하면 됩니다. 마찬가지로 싱크에 특정 모델의 이벤트가 필요한 경우에는 해당 이벤트 모델용으로만 출력 어댑터를 디자인하면 됩니다. 그러나 대부분의 응용 프로그램에서는 특정 이벤트 유형에 대해 모든 이벤트 모델이 필요할 수 있습니다. 각 이벤트 모델에 대해 형식화된 어댑터나 형식화되지 않은 어댑터를 빌드하는 것이 좋습니다. 이벤트 모델에 대한 자세한 내용은 StreamInsight 서버 개념을 참조하십시오.

    입력 및 출력 AdapterFactory 클래스를 사용하면 이러한 어댑터를 함께 패키지로 만들 수 있습니다. 구성 매개 변수를 기반으로 쿼리 바인딩 시 올바른 어댑터를 인스턴스화할 수 있습니다.

  • 해당하는 어댑터 기본 클래스를 선택합니다.

    이벤트 유형 및 모델에 따라 해당하는 어댑터 기본 클래스를 선택합니다. 클래스 명명법은 [Typed][Point | Interval | Edge][Input | Output] 패턴을 따릅니다. 형식화되지 않은 어댑터에는 형식화된 접두사가 없습니다.

    어댑터 유형 입력 어댑터 기본 클래스 출력 어댑터 기본 클래스
    형식화된 지점 TypedPointInputAdapter TypedPointOutputAdapter
    형식화되지 않은 지점 PointInputAdapter PointOutputAdapter
    형식화된 간격 TypedIntervalInputAdapter TypedIntervalOutputAdapter
    형식화되지 않은 간격 IntervalInputAdapter IntervalOutputAdapter
    형식화된 가장자리 TypedEdgeInputAdapter TypedEdgeOutputAdapter
    형식화되지 않은 가장자리 EdgeInputAdapter EdgeOutputAdapter

    자세한 내용은 Microsoft.ComplexEventProcessing.Adapters를 참조하십시오.

  • 입력 및 출력 AdapterFactory 클래스를 디자인합니다.

    AdapterFactory는 어댑터용 컨테이너 클래스입니다. 팩터리 클래스를 구현해야 합니다. 기본 팩터리 클래스는 다음과 같이 구성됩니다.

    어댑터 유형 입력 어댑터 기본 클래스 출력 어댑터 기본 클래스
    형식화됨 ITypedInputAdapterFactory ITypedOutputAdapterFactory
    형식화되지 않음 IInputAdapterFactory IOutputAdapterFactory
    복구 지원과 함께 형식화됨 IHighWaterMarkTypedInputAdapterFactory IHighWaterMarkTypedOutputAdapterFactory
    복구 지원과 함께 형식화되지 않음 IHighWaterMarkInputAdapterFactory IHighWaterMarkOutputAdapterFactory

    팩터리 클래스는 다음과 같은 용도로 사용됩니다.

    • 지정된 장치 클래스(CSV 파일, database or your report server without the permission of the system administrator. 데이터베이스, 웹 서버 공통 로그 형식) 또는 응용 프로그램 요구 사항에 대해 서로 다른 어댑터 구현 간에 리소스를 공유할 수 있도록 하며 어댑터 생성자로 구성 매개 변수를 쉽게 전달할 수 있도록 합니다. 예를 들어 응용 프로그램에 세 이벤트 모델(지점, 간격, 가장자리)이 모두 필요한 경우 단일 팩터리가 각 이벤트 모델에 대해 하나씩 세 어댑터 구현을 지원할 수 있습니다. 응용 프로그램에 데이터베이스 테이블 등의 동일한 이벤트 원본이 있는데 원본이 실행되는 쿼리를 기준으로 동일 원본에서 여러 이벤트 페이로드 구조를 생성하는 경우도 예로 들 수 있습니다. 이 경우 단일 팩터리가 각 페이로드 구조를 처리하는 어댑터 구현을 지원할 수 있습니다.

    • 서버 런타임에 대한 어댑터의 게이트웨이를 제공합니다. 어댑터 개발자는 어댑터 클래스에 대해 어댑터 팩터리에서 Create()Dispose() 메서드를 구현해야 합니다. 이러한 메서드는 쿼리 시작 및 종료 중에 서버에서 호출합니다.

    • 런타임 이전 구성 정보에 대한 어댑터의 게이트웨이를 제공합니다. 특히 형식화되지 않은 어댑터의 경우 쿼리 바인딩 중에 제공되는 구성 매개 변수의 구조에서 각 필드 유형을 확인해야 하므로 이 사항이 매우 중요합니다. 팩터리 클래스에 구성 구조를 정의한 다음 Create() 메서드를 통해 이 구성 구조를 어댑터 클래스의 생성자 메서드로 전달할 수 있습니다. 이 구성 구조는 DataContractSerialization을 사용하여 직렬화합니다. 이 제약 조건 외에도, 개발 방법에서는 이 구성 구조를 채우고 어댑터 생성자에서 사용하는 방법 측면에서 매우 유연한 정의와 사용 방법을 선택할 수 있습니다.

    • AdapterFactory를 사용하면 CTI(현재 시간 증분)를 입력 어댑터의 큐에 명시적으로 넣지 않고도 생성할 수 있습니다. 사용자는 어댑터 팩터리 클래스에서 TypedDeclareAdvanceTimePolicy(형식화된 어댑터 팩터리의 경우) 및 IDeclareAdvanceTimePolicy(형식화되지 않은 어댑터 팩터리의 경우) 인터페이스를 구현하여 CTI 빈도 및 타임스탬프를 지정할 수 있습니다. 이렇게 하면 어댑터 코드가 단순해지며 팩터리가 해당 어댑터 인스턴스를 통해 생성하는 모든 이벤트 스트림에 영향을 줄 수 있습니다. 자세한 내용은 [AdvanceTimeSettings Class](assetId:///AdvanceTimeSettings Class?qualifyHint=False&autoUpgrade=True)를 참조하십시오.

    • 복구 가능한 응용 프로그램에서는 누락된 이벤트를 재생할 수 있도록 입력 어댑터에 상위 워터마크를 제공하고 중복되는 이벤트를 제거할 수 있도록 출력 어댑터에 상위 워터마크와 오프셋을 제공함으로써 복구를 지원합니다. 자세한 내용은 StreamInsight 복구를 참조하십시오.

  • 어댑터를 빌드 및 테스트합니다.

    어댑터를 .NET 어셈블리로 컴파일 및 빌드합니다. 그런 다음 입력 어댑터에서 이벤트를 읽어 복잡한 쿼리 처리를 수행하지 않고 출력 어댑터로 이벤트를 출력하는 간단한 통과 쿼리에서 어댑터의 기본 작업을 테스트합니다. 그러면 어댑터가 장치에서 읽고 쓰기를 수행하며 이벤트를 큐에 넣고 큐에서 제거할 수 있는지 확인할 수 있습니다.

어댑터 상태 시스템

어댑터와 StreamInsight 서버 간의 상호 작용을 정의하는 상태 시스템은 입력 어댑터와 출력 어댑터에 대해 동일합니다. 상태 시스템은 일관성 있는 개발 모델을 제공하므로 이는 중요한 사항입니다. 다음 그림에 상태 시스템이 나와 있습니다.

어댑터가 큐에 삽입하고 큐에서 제거하는 상태를 나타낸 다이어그램

이 상태 시스템의 주요 기능과 상태 시스템 작동을 위한 요구 사항은 다음과 같습니다.

  • Start() 및 **Resume()**은 StreamInsight 서버에서 호출하는 메서드이며 어댑터 개발자가 구현해야 합니다. 또한 어댑터 개발자는 어댑터 클래스에 대한 생성자 메서드와 기본 클래스에서 상속되는 Dispose() 메서드도 구현해야 합니다.

  • 그리고 어댑터 구현에서는 어댑터 SDK에서 제공되는 다음 메서드를 호출해야 합니다.

    • 입력 어댑터용 Enqueue(). EnqueueOperationResult.Success 또는 EnqueueOperationResult.Full 값이 반환됩니다.

    • 출력 어댑터용 Dequeue(). DequeueOperationResult.Success 또는 DequeueOperationResult.Empty 값이 반환됩니다.

    • Ready(). TRUE 또는 FALSE 부울 값이 반환됩니다.

    • Stopped(). TRUE 또는 FALSE 부울 값이 반환됩니다.

  • StreamInsight 서버는 관리자 또는 쿼리 개발자가 서버 API의 메서드를 통해 쿼리 실행을 중지하면 사용자를 대신해 내부 메서드(**StopQuery()**로 표시됨)를 비동기 방식으로 호출합니다.

  • Enqueue() 및 **Dequeue()**를 호출하면 어댑터가 다음 상태 중 하나일 때 각각 FullEmpty 상태가 반환됩니다.

    • Suspended

    • Stopping

  • Enqueue() 및 **Dequeue()**를 호출하면 어댑터가 다음 상태 중 하나일 때 예외가 발생합니다.

    • Created

    • Stopped

  • **Ready()**를 호출하면 어댑터가 다음 상태 중 하나일 때 예외가 발생합니다.

    • Created

    • Running

    • Stopped

  • 어댑터는 작업 과정 중에 이 5가지 상태(Created, Running, Suspended, Stopping, Stopped) 중 일부 또는 모두로 전환됩니다. 상태 전환은 StreamInsight 서버가 Start() 또는 **Resume()**을 호출하기 전과 어댑터가 Enqueue(), Dequeue(), Ready() 및 **Stopped()**를 호출한 후에 발생합니다.

  • StreamInsight 서버와 어댑터는 같은 스레드를 공유하지 않습니다. 서버는 항상 별도의 작업자 스레드에서 Start() 또는 **Resume()**을 호출하며, 어댑터 대신 운영 체제 스레드 풀에서 이 스레드를 가져옵니다. 즉, Start()Resume() 메서드는 작업자 스레드를 필요한 경우(예: 비동기 읽기 또는 쓰기를 위해 더 많은 스레드 생성) 완전하고 유연하게 사용할 수 있습니다. 그러므로 이 스레드에서 시스템 리소스를 사용할 때는 주의해야 하며 최선의 방법을 사용해야 합니다.

  • API를 사용하는 경우 **Start()**와 Resume() 작업(스레드) 간의 기본적 동기화를 수행하지 않아도 됩니다. 서버는 항상 어댑터가 **Ready()**를 호출한 후에만 **Resume()**을 호출합니다. 그러나 특히 비동기 I/O 시나리오의 경우 장치에 연결하는 읽기, 쓰기 또는 버퍼링 이벤트 태스크 시 동기화를 수행해야 할 수도 있습니다. 이 경우에는 비블로킹 I/O를 사용하는 것이 가장 좋습니다.

  • 어댑터가 유휴 상태일 수 있는 경우 어댑터는 상태를 주기적으로 검사해 중지 요청이 있었는지를 확인해야 합니다.

어댑터와 서버의 상호 작용 수명

StreamInsight 서버와 어댑터 간의 핸드셰이크는 항상 동기 방식으로 진행되므로, 해당 실행의 임의 지점에서 어댑터가 상태를 확인하고 그에 따라 대응할 수 있습니다. 어댑터와 StreamInsight 서버 상호 작용의 수명에는 다음 작업이 포함됩니다. 이들 작업은 위 그림에 나왔던 상태 시스템에 해당합니다.

  • Created

    StreamInsight 서버 API에서 해당 호출을 수행해 쿼리를 시작하면 어댑터 인스턴스와 StreamInsight 서버의 상호 작용이 시작됩니다.

  • Running

    서버가 어댑터를 Running 상태로 설정하고 어댑터에서 비동기 방식으로 **Start()**를 호출하며 이 호출을 한 번만 수행하도록 지정합니다. Running 상태의 어댑터는 서버로 들어오거나 서버에서 나가는 이벤트를 각각 큐에 넣거나 큐에서 제거할 수 있습니다.

    정상 상태에서 어댑터는 대부분의 시간 동안 Running 상태입니다. Start() 메서드에서 판독기 또는 작성기 루틴(가급적 별도의 스레드에 있는 루틴)을 호출한 다음 Start() 루틴에서 결과를 반환하여 작업자 스레드를 신속하게 포기하는 디자인 패턴을 사용하는 것이 좋습니다.

    판독기 루틴(ProduceEvents()라는 예제 루틴을 가정함)은 원본에서 이벤트를 읽은 다음 **Enqueue()**를 호출하여 이벤트를 서버로 밀어넣습니다. 출력 어댑터의 경우에는 작성기 루틴(ConsumeEvents()라는 예제 루틴을 가정함)이 **Dequeue()**를 호출하여 서버에서 이벤트를 끌어와 싱크에 씁니다.

  • Suspended

    서버가 큐에 넣은 이벤트를 받을 수 없거나 큐에서 제거할 이벤트를 출력할 수 없는 경우 입력 또는 출력 어댑터는 Suspended 상태가 됩니다. 그러면 Enqueue() 및 **Dequeue()**가 호출되어 각각 FULL 및 EMPTY 상태가 반환됩니다. Suspended 상태에서는 데이터베이스의 마지막으로 읽은 레코드 위치나 파일의 줄 위치를 저장하는 등의 정리 작업을 구현할 수 있습니다. 이 선택적 섹션이 끝나면 Ready() 메서드를 호출하여 어댑터를 재개할 준비가 되었음을 서버에 알려야 합니다. 루틴이 Start() 자체와 같은 작업자 스레드에서 실행 중이라면 Start() 루틴 자체에서 결과를 반환해야 합니다.

  • 서버는 Ready() 호출에 대한 응답으로 어댑터를 Running 상태로 되돌리고 항상 다른 작업자 스레드에서 **Resume()**을 비동기 방식으로 호출합니다. **Resume()**이 마지막으로 실패한 반복을 큐에 넣거나 큐에서 제거한 다음 ProduceEvents() 또는 ConsumeEvents()를 호출하도록 디자인할 수 있습니다. 이 패턴은 어댑터가 Stopped 또는 Stopping 상태로 전환될 때까지 계속할 수 있습니다.

  • Stopping

    Running 또는 Suspended 상태가 지정된 임의의 지점에서 서버는 쿼리를 중지하라는 비동기 요청에 대한 응답으로 어댑터를 Stopping 상태로 이동할 수 있습니다. 이 상태에서 Enqueue() 또는 **Dequeue()**를 호출하면 각각 FULL 또는 EMPTY 상태도 반환됩니다.

    Stopping 상태에서는 어댑터 구현이 올바르게 중지 준비를 할 수 있는 준비 영역이 제공됩니다. 어댑터가 가져온 모든 리소스(스레드, 메모리)를 포기하고 Stopped() 메서드를 호출하도록 구현할 수 있습니다. 이 메서드를 호출할 때까지는 서버가 어댑터를 중지하지 않습니다.

    어댑터는 비동기 방식으로 Stopping 상태로 전환될 수 있습니다. 이 경우 어댑터가 Stopping 상태로 전환되었음을 검색하기 위한 방법이 필요합니다. 위에서 설명한 것처럼 이 경우에는 어댑터가 일시 중지되면 **Ready()**를 호출하는 디자인 패턴을 사용합니다. 이에 대한 응답으로 서버는 Resume() 메서드를 한 번 더 호출하여 Resume() 메서드에서 Stopping 상태를 검색할 수 있도록 합니다. Stopping 상태 확인 기능을 Start()Resume() 구현의 첫 번째 코드 블록으로 배치하는 것이 가장 효과적입니다.

  • Stopped

    어댑터 코드에서는 모든 지점에서 **Stopped()**를 호출할 수 있습니다. 그러면 어댑터가 Stopped 상태로 전환됩니다. 효율적으로 디자인하려면 **Stopped()**를 호출하기 전에 어댑터가 가져온 리소스를 정리하는 것이 좋습니다.

    System_CAPS_ICON_important.jpg 중요


    Stopped() 메서드를 호출하지 않으면 쿼리와 연결된 메모리의 마지막 페이지가 할당된 상태로 유지됩니다. 그러면 약간의 메모리 누수가 발생할 수 있는데, 프로세스에 쿼리 시작 및 중지 주기가 많으면 시간이 지남에 따라 메모리 누수가 누적될 수 있습니다.

    Stopped 상태에서 어댑터는 StreamInsight 서버 관련 구문 또는 이벤트 메모리를 참조하거나 큐에 넣기 또는 큐에서 제거 작업을 수행할 수 없습니다. 이러한 동작을 수행하면 예외가 발생합니다. 그러나 운영 체제 및 장치 연결 정리 작업은 계속할 수 있습니다.

다양한 입력 및 출력 어댑터 및 어댑터 팩터리의 예를 보려면 StreamInsight 샘플에서 제공되는 예를 참조하십시오.

참고 항목

StreamInsight 서버 개념
StreamInsight 서버 아키텍처