본문 바로가기

Java/Vert.x

버텍스 코어: 컨텍스트(Context)

이 문서의 내용

    더보기

    Context는 Vertx 객체가 핸들러에게 이벤트를 제공하거나 버티클이 실행 또는 중지되는 등의 메소드를 호출하는 과정에서 사용됩니다.

    일반적으로 Context는 이벤트 루프 컨텍스트(Event-Loop context)이며 특정 이벤트 루프 스레드와 연결됩니다.

    따라서 해당 Context에 대한 실행은 모두 동일한 이벤트 루프 스레드에서 실행됨을 의미합니다.

    반면 워커 버티클 또는 인라인 차단 코드(executeBlocking)을 사용하는 경우 워커 컨텍스트(Worker context)이며 워커 스레드 풀의 워커 스레드와 연결됩니다.

    Context를 검색하려면 getOrCreateContext()를 사용합니다.

    Context context = vertx.getOrCreateContext();

    이 함수는 Vertx 클래스의 정적 메소드 currentContext()로 대체 될 수 있습니다.

    아직 Context가 할당되지 않았다면 Null을 리턴합니다.

    Context context = Vertx.currentContext();

    Context가 현재 어떤 스레드와 연결되어 있는지 확인 할 수 있습니다.

    Context context = vertx.getOrCreateContext();
    if (context.isEventLoopContext()) {
    	System.out.println("Context attached to Event Loop");
    } else if (context.isWorkerContext()) {
    	System.out.println("Context attached to Worker Thread");
    } else if (context.isMultiThreadedWorkerContext()) {
    	System.out.println("Context attached to Worker Thread - multi threaded worker");
    } else if (! Context.isOnVertxThread()) {
    	System.out.println("Context not attached to a thread managed by vert.x");
    }

    runOnContext

    Context를 사용하면 코드를 비동기로 실행 할 수 있습니다.

    runOrContext()를 호출하면 Context에 코드를 발행(Dispatched)하고, 나중에 발행된 이벤트는 Context와 연결된 스레드에서 처리합니다.

    context.runOnContext(ar -> { System.out.println("this code will be executed asynchronously in same context-same event loop thread - "  + Thread.currentThread().getId()); });
    		
    System.out.println("this code will be executed right now current thread - " + Thread.currentThread().getId());
    코드 비고
    Line 1 나중에 실행되는 이벤트 이 코드는 Context에 전달되어 나중에 실행되는 이벤트입니다.
    이때 Context는 이벤트 루프 컨텍스트로, 나중에 실행될 때에도 동일한 이벤트 루프 스레드에서의 실행을 보장합니다.
    Line 3 즉시 실행되는 코드 이 코드는 즉시 실행됩니다.

    코드를 실행하면 다음과 같이 두 개의 코드가 동일한 스레드에서 실행됨을 알 수 있습니다.

    this code will be executed right now current thread - 19
    this code will be executed asynchronously in same context-same event loop thread - 19

    Context에서 공유 데이터 접근

    동일한 Context에서 실행되는 핸들러는 데이터를 공유 할 수 있습니다.

    Context는 공유 데이터를 저장하고 검색하는 등의 기능을 제공합니다.

    final Context context = vertx.getOrCreateContext();
    context.put("data", "hello");
    context.runOnContext((v) -> {
    	String hello = context.get("data");
    });
    더보기

    Context의 config() 메소드로 버티클의 설정 데이터에 엑세스 할 수 있습니다.

    이와 관련해서는 Passing configuration to a verticle 문서를 참고합니다.

    정리 및 복습

    • Context는 대표적으로 이벤트 루프 컨텍스트워커 컨텍스트가 있습니다.
    이벤트 루프 컨텍스트 워커 컨텍스트 
    이벤트 루프 컨텍스트는 이벤트 루프 스레드와 연결됩니다.
    이벤트 루프 컨텍스트가 실행하는 이벤트는 모두 동일한 이벤트 루프 스레드에서 실행을 보장합니다.
    워커 컨텍스트는 워커 스레드 풀의 워커 스레드와 연결됩니다.
    워커 컨텍스트가 실행하는 이벤트는 워커 스레드 풀에서의 실행을 보장하지만, 항상 동일한 스레드에서 실행되는 것은 아닙니다.
    • Context에 나중에 실행 될 이벤트를 전달하려면 runOrContext()를 호출합니다.
    • Context를 사용하면 핸들러 간 데이터를 공유 할 수 있습니다.
    • 공유 데이터를 읽기/쓰기 하려면 Context에서 get() 또는 put()을 호출합니다.