콘텐츠로 이동

English | 한국어

Core 스펙 목차 | 이전: 공개 계약 관리 | 다음: Message

Context

이 장이 정의하는 것 — Context가 무엇을 소유하고, 어떻게 만들고 설정하며 안전하게 종료하는지의 공개 C ABI 계약.

1. Context 개요

zlink의 Context는 I/O 처리 thread와 socket을 담는 최상위 container다. 모든 application은 다른 zlink API를 쓰기 전에 Context를 하나 이상 만들어야 하고, 모든 socket은 반드시 어떤 Context에 속한다.

이 문서는 Context를 만들고, 옵션으로 설정하고, 안전하게 종료하는 계약을 정의한다. 대상 독자는 이 계약을 C API와 각 언어 binding으로 옮기는 개발자다.

관련 계약의 소유 문서는 다음과 같다.

관련 계약 정의하는 문서
Auto HWM budget 계산·admission과 관련 함수 Auto HWM
socket 생성·옵션·송수신 Socket 공통
message lifecycle와 ownership Message

2. Context가 소유하는 것

Context는 다음을 소유한다.

  • I/O thread pool — 네트워크 송수신을 실제로 처리하는 I/O thread 집합이다. thread 개수, 스케줄링 우선순위와 CPU affinity를 Context 옵션으로 정한다.
  • socket container — 이 Context로 만든 모든 socket의 상위다. 동시에 열 수 있는 socket 수의 상한도 Context 옵션이다.
  • 공유 설정 — thread 이름, 최대 message 크기, 그리고 socket queue의 크기를 자동으로 정하는 Auto HWM 정책처럼 context 전체에 적용하는 값이다.

Context는 thread-safe하다. 여러 thread가 같은 Context 핸들을 동시에 공유하고 옵션을 조회·설정할 수 있다.

3. 수명과 종료

Context의 수명은 만들기 → 사용 → 종료 신호 → 자원 해제 순으로 진행한다.

  • 만들기zlink_ctx_new가 기본 옵션 값으로 Context를 만든다.
  • 종료 신호zlink_ctx_shutdown은 이 Context에 속한 socket의 모든 blocking 작업이 즉시 ETERM으로 풀리도록 신호만 보낸다. 자원은 해제하지 않는 non-blocking 호출이다. 이렇게 풀린 zlink_recvZLINK_RECV_TERMINATED를 반환하고 receive output을 바꾸지 않는다. 풀린 zlink_sendZLINK_SUBMIT_TERMINATED를 반환하고 다른 submit 실패와 같이 모든 입력 슬롯을 소비해 빈 initialized 상태로 두며 completion ID 0을 돌려준다.
  • 자원 해제zlink_ctx_term이 Context를 파괴한다. 이 호출은 Context 안에서 만든 모든 socket이 닫힐 때까지 blocking될 수 있다. 각 Context는 정확히 한 번만 term한다.

여러 thread가 socket을 사용하는 중이라면 term 전에 shutdown을 먼저 호출해 deadlock을 피한다. shutdown 없이 term만 호출하면 socket이 닫히기를 기다리며 멈출 수 있기 때문이다. ZLINK_CTX_OPT_BLOCKY0으로 설정하면 이후 생성하는 socket의 기본 LINGER0이 되어, socket이 전달하지 못한 message를 기다리지 않고 닫히므로 term이 빨리 반환된다. term 자체는 이 옵션과 무관하게 내부 정리가 끝날 때까지 기다린다.

%%{init: {'sequence': {'actorFontSize': '18px', 'messageFontSize': '18px', 'noteFontSize': '18px', 'boxMargin': 8, 'width': 140}, 'themeVariables': {'fontSize': '18px'}}}%%
sequenceDiagram
    participant App as Application
    participant Ctx as Context
    participant S as Socket들
    App->>Ctx: zlink_ctx_new()
    Note over Ctx: I/O thread pool 생성
    App->>S: socket 생성·사용
    App->>Ctx: zlink_ctx_shutdown() (non-blocking)
    Ctx-->>S: 모든 blocking 작업 즉시 ETERM
    App->>S: 각 socket close
    App->>Ctx: zlink_ctx_term()
    Note over Ctx: 모든 socket 닫힐 때까지 대기 후 파괴

4. 옵션

각 option의 값, 타입, 접근 API, 초기값과 적용 시점은 다음과 같다. 표의 set/get은 zlink_ctx_set/zlink_ctx_get, set_data/get_data는 같은 이름의 data API를 뜻한다.

Option (ZLINK_ 접두사) 값·Type·접근 초기값 또는 read-only 값 적용 시점
IO_THREADS 1; int, set/get 4 설정값은 즉시 조회되며 runtime이 처음 시작될 때 pool 크기로 고정됨
MAX_SOCKETS 2; int, set/get 4095를 poller limit에 맞춰 줄인 값 설정값은 즉시 조회되며 runtime이 처음 시작될 때 slot capacity로 고정됨
SOCKET_LIMIT 3; int, get-only 65535를 poller limit에 맞춰 줄인 값 항상 현재 platform hard limit을 반환함
THREAD_PRIORITY 22; int, set/get -1 설정 뒤 시작하는 I/O thread에 적용됨
THREAD_SCHED_POLICY 4; int, set/get -1 설정 뒤 시작하는 I/O thread에 적용됨
MSG_T_SIZE 6; int, get-only sizeof(zlink_msg_t)64 compile-time ABI 크기를 반환함
THREAD_AFFINITY_CPU_ADD 7; int, set-only 빈 CPU 집합 CPU를 즉시 집합에 추가하고 이후 시작하는 I/O thread에 적용함
THREAD_AFFINITY_CPU_REMOVE 8; int, set-only 빈 CPU 집합 CPU를 즉시 집합에서 제거하고 이후 시작하는 I/O thread에 적용함
THREAD_NAME_PREFIX 9; byte string, set_data/get_data 길이 0 설정 뒤 시작하는 I/O thread의 이름에 적용함
CTX_OPT_BLOCKY 10; int, set/get 1 설정 뒤 만드는 socket의 기본 LINGER에 적용함
CTX_OPT_AUTO_HWM_ENABLE 12; int, set/get 1 저장한 뒤 기존 socket을 포함한 재계산을 예약함
CTX_OPT_AUTO_HWM_RECALC_DEBOUNCE_MS 14; int, set/get 3000 ms 저장한 debounce로 재계산을 예약함
CTX_OPT_AUTO_HWM_PROFILE 17; int, set/get BALANCED 저장한 뒤 기존 socket을 포함한 재계산을 예약함
CTX_OPT_AUTO_HWM_MEMORY_LIMIT_BYTES 19; uint64_t, set_data/get_data 0 저장한 뒤 기존 socket을 포함한 재계산을 예약함
CTX_OPT_AUTO_HWM_RUNTIME_MEMORY_LIMIT_BYTES 20; uint64_t, set_data/get_data 0 저장한 뒤 기존 socket을 포함한 재계산을 예약함
CTX_OPT_AUTO_HWM_CORE_BUDGET_BYTES 21; uint64_t, set_data/get_data 0 저장한 뒤 기존 socket을 포함한 재계산을 예약함
typedef enum zlink_auto_hwm_profile_t
{
    ZLINK_AUTO_HWM_PROFILE_COMPACT = 0,      // memory 비율이 가장 작다 — 메모리를 아껴야 할 때
    ZLINK_AUTO_HWM_PROFILE_LOW_LATENCY = 1,  // queue를 짧게 유지해 지연을 줄인다
    ZLINK_AUTO_HWM_PROFILE_BALANCED = 2,     // 기본값. memory와 처리량을 절충한다
    ZLINK_AUTO_HWM_PROFILE_THROUGHPUT = 3    // memory 비율이 가장 크다 — 대용량 처리가 우선일 때
} zlink_auto_hwm_profile_t;

각 profile의 정확한 memory 비율, 고정 cap과 역할별 하한·상한은 Auto HWM §2가 소유한다.

Auto HWM byte 옵션 세 개(MEMORY_LIMIT_BYTES, RUNTIME_MEMORY_LIMIT_BYTES, CORE_BUDGET_BYTES)가 어떤 budget을 계산하고 어떻게 admission에 쓰이는지는 Auto HWM이 소유한다.

4.1 기본값

#define ZLINK_IO_THREADS_DFLT           4  // 기본 I/O thread 수
#define ZLINK_MAX_SOCKETS_DFLT          4095  // 기본 최대 socket 수
#define ZLINK_THREAD_PRIORITY_DFLT      -1  // 기본 우선순위 (OS 기본값)
#define ZLINK_THREAD_SCHED_POLICY_DFLT  -1  // 기본 스케줄링 정책 (OS 기본값)
#define ZLINK_CTX_AUTO_HWM_ENABLE_DFLT  1  // 자동 HWM 기본 활성 (끄거나 수동 HWM 미설정 시 balanced)
#define ZLINK_CTX_AUTO_HWM_RECALC_DEBOUNCE_MS_DFLT 3000  // 재계산 기본 debounce (ms)
#define ZLINK_CTX_AUTO_HWM_PROFILE_DFLT ZLINK_AUTO_HWM_PROFILE_BALANCED  // 기본 profile
#define ZLINK_CTX_AUTO_HWM_MEMORY_LIMIT_BYTES_DFLT ((uint64_t) 0)  // 명시적 limit 미설정
#define ZLINK_CTX_AUTO_HWM_RUNTIME_MEMORY_LIMIT_BYTES_DFLT ((uint64_t) 0)  // runtime hint 없음
#define ZLINK_CTX_AUTO_HWM_CORE_BUDGET_BYTES_DFLT ((uint64_t) 0)  // 수동 Core budget 미설정

SNDBUF / RCVBUF 기본값은 -1이다. 이 값은 zlink가 OS socket buffer 크기를 직접 정하지 않고 OS 기본값과 TCP 자동 조정에 맡긴다는 뜻이다. auto-HWM profile은 이 값을 자동으로 바꾸지 않는다.

5. 함수

새 zlink context를 생성한다.

ZLINK_EXPORT void *zlink_ctx_new(void);

기본 옵션 값으로 새 context를 할당하고 초기화한다. Context는 I/O thread pool을 관리하며 socket 생성의 기반이 된다. 모든 socket은 context와 연결되어야 한다. Context가 더 이상 필요하지 않으면 zlink_ctx_term으로 해제한다.

반환값: 성공 시 context 핸들, 실패 시 NULL (errno가 설정됨).

스레드 안전성: 모든 스레드에서 안전하게 호출할 수 있다. 반환된 context 핸들은 thread 간에 공유할 수 있다.

참고: zlink_ctx_term, zlink_ctx_set


Context를 종료하고 관련된 모든 자원을 해제한다.

ZLINK_EXPORT zlink_close_result_t zlink_ctx_term(void *context_);

Context를 파괴한다. 이 호출은 context 내에서 생성된 모든 socket이 닫힐 때까지 blocking될 수 있다. Context에 속한 socket의 blocking 작업은 zlink_ctx_shutdown이 호출되거나 모든 socket이 닫힌 후 ETERM을 반환한다. 각 context는 정확히 한 번만 종료해야 한다.

반환값: 성공 시 ZLINK_CLOSE_OK, 실패 시 zlink_close_result_t 값. zlink_errno()는 진단용 내부 errno를 그대로 유지한다.

에러: - EFAULT -- 유효하지 않은 context 핸들. - EINTR -- signal에 의해 종료가 중단됨; 재시도할 수 있다.

스레드 안전성: 모든 스레드에서 안전하게 호출할 수 있지만, context당 정확히 한 번만 호출해야 한다. 이 호출이 반환된 후에는 context 핸들을 사용하지 않는다.

참고: zlink_ctx_new, zlink_ctx_shutdown


Context를 즉시 종료한다.

ZLINK_EXPORT zlink_close_result_t zlink_ctx_shutdown(void *context_);

이 context에 속한 socket의 모든 blocking 작업이 ETERM과 함께 즉시 반환되도록 신호를 보낸다. 이것은 종료를 시작하지만 자원을 해제하지 않는 non-blocking 호출이다. 최종 정리를 위해 이후에 zlink_ctx_term을 호출해야 한다. term 전에 shutdown을 호출하면 여러 thread에서 socket을 사용할 때 deadlock을 방지할 수 있다.

반환값: 성공 시 ZLINK_CLOSE_OK, 실패 시 zlink_close_result_t 값. zlink_errno()는 진단용 내부 errno를 그대로 유지한다.

에러: - EFAULT -- 유효하지 않은 context 핸들.

스레드 안전성: 모든 스레드에서 안전하게 호출할 수 있다.

참고: zlink_ctx_term


Context 옵션을 설정한다.

ZLINK_EXPORT zlink_config_result_t zlink_ctx_set(void *context_, zlink_ctx_option_t option_, int optval_);

socket이 생성되기 전 또는 후에 context를 구성한다. 유효한 옵션 이름과 의미는 §4 옵션 목록을 참조한다. 단, ZLINK_IO_THREADSZLINK_MAX_SOCKETS는 설정 자체는 언제든 성공하고 조회에도 반영되지만, 실제 I/O thread pool과 socket 슬롯 용량은 context runtime이 처음 시작될 때의 값으로 한 번 고정되며 그 후에 값을 바꿔도 런타임 용량은 바뀌지 않는다. runtime은 첫 socket 생성에서 시작되지만, 그 전에 양수 debounce로 Auto HWM 재계산이 예약되는 등 control runtime이 먼저 요청되면 그 시점에 시작된다. ZLINK_CTX_OPT_AUTO_HWM_ENABLE은 이미 만들어진 socket에도 적용된다 — 변경은 자동 재계산을 예약하며(기본 debounce 3000 ms), 그 전에 새 계획이 필요하면 zlink_ctx_auto_hwm_recalculate를 호출한다. 아직 수동 SNDHWM / RCVHWM 값을 주지 않은 socket만 자동 정책으로 다시 계산한다. 값을 0으로 바꾸면 현재 pipe에 마지막으로 적용한 HWM을 유지하고 이후 자동 재계산에서 제외하며 snapshot의 planning-active flag를 지운다. ZLINK_CTX_OPT_AUTO_HWM_PROFILE은 다음 자동 HWM 계산에서 쓰는 profile을 바꾸며, runtime 중에도 안전하게 조정할 수 있다. Profile은 memory 비율과 역할별 byte 하한·상한을 선택한다. SNDBUF / RCVBUF 기본값은 -1이며, auto-HWM profile은 이 값을 자동으로 바꾸지 않는다. 세 Auto HWM byte 옵션은 zlink_ctx_set으로 설정할 수 없고 EINVAL로 실패한다. (계약은 Auto HWM 참조)

반환값: 성공 시 ZLINK_CONFIG_OK, 실패 시 zlink_config_result_t 값. zlink_errno()는 진단용 내부 errno를 그대로 유지한다.

에러: - EINVAL -- 알 수 없는 옵션 또는 유효하지 않은 값. - EFAULT -- 유효하지 않은 context 핸들 (ZLINK_CONFIG_INVALID_HANDLE).

스레드 안전성: 모든 스레드에서 안전하게 호출할 수 있다.

참고: zlink_ctx_set_data, zlink_ctx_get


byte 버퍼로 context 옵션을 설정한다.

ZLINK_EXPORT zlink_config_result_t zlink_ctx_set_data(void *context_,
                                         zlink_ctx_option_t option_,
                                         const void *optval_,
                                         size_t optvallen_);

세 Auto HWM byte 옵션은 정확히 sizeof(uint64_t) byte를 받는다. 값 0은 unlimited가 아니라 해당 입력을 설정하지 않았다는 뜻이다. 다른 크기와 위 enum에 없는 context 옵션 값은 ZLINK_CONFIG_INVALID_ARGUMENT로 실패한다. 유효한 값을 설정하면 값을 저장한 뒤 Auto HWM 재계산을 예약한다. 새 budget이 현재 수동 HWM과 자동 하한을 함께 수용하지 못해도 setter는 성공하며, planner는 자동 하한을 낮추지 않고 budget snapshot에 ZLINK_AUTO_HWM_BUDGET_FLAG_INSUFFICIENT를 설정한다. (계약은 Auto HWM 참조)

ZLINK_THREAD_NAME_PREFIX에는 null 종료 문자열을 optval_로 전달하고 strlen(prefix) + 1optvallen_으로 전달한다. 접두사는 platform thread 이름 제한에 맞춰 최대 16바이트(optvallen_ <= 16)로 제한된다.

반환값: 성공 시 ZLINK_CONFIG_OK, 실패 시 zlink_config_result_t 값. zlink_errno()는 진단용 내부 errno를 그대로 유지한다.

에러: - EINVAL -- 알 수 없는 옵션 또는 유효하지 않은 값. - EFAULT -- 유효하지 않은 context 핸들 (ZLINK_CONFIG_INVALID_HANDLE).

스레드 안전성: 모든 스레드에서 안전하게 호출할 수 있다.

참고: zlink_ctx_set, zlink_ctx_get_data, zlink_ctx_get


호출자가 제공한 저장 공간으로 context 옵션을 조회한다.

ZLINK_EXPORT zlink_config_result_t zlink_ctx_get_data(void *context_,
                                         zlink_ctx_option_t option_,
                                         void *optval_,
                                         size_t *optvallen_);

세 Auto HWM byte 옵션에는 uint64_t output buffer가 필요하고, 호출할 때 *optvallen_이 정확히 sizeof(uint64_t)여야 한다. 더 큰 임시 buffer나 4-byte 크기를 포함해 그 밖의 크기는 값을 잘라 쓰거나 일부만 채우지 않고 ZLINK_CONFIG_INVALID_ARGUMENTerrno == EINVAL로 실패한다. 이때 필요한 크기인 sizeof(uint64_t)*optvallen_에 기록한다. 성공해도 같은 크기를 유지한다.

ZLINK_THREAD_NAME_PREFIX도 이 함수로 조회한다. *optvallen_에는 output buffer의 용량을 전달한다. 용량이 저장된 prefix 길이보다 작으면 필요한 길이를 *optvallen_에 기록하고 ZLINK_CONFIG_INVALID_ARGUMENTEINVAL로 실패한다. 충분하면 prefix byte를 복사하고 *optvallen_을 복사한 길이로 갱신한다.

반환값: 성공 시 ZLINK_CONFIG_OK, 실패 시 zlink_config_result_t 값. zlink_errno()는 진단용 내부 errno를 그대로 유지한다.

에러: - EINVAL -- 알 수 없는 option, 잘못된 output 크기 또는 NULL output pointer (ZLINK_CONFIG_INVALID_ARGUMENT). - EFAULT -- 유효하지 않은 context handle (ZLINK_CONFIG_INVALID_HANDLE).

스레드 안전성: 모든 스레드에서 안전하게 호출할 수 있다.

참고: zlink_ctx_set_data, zlink_ctx_get


Context 옵션을 조회한다.

ZLINK_EXPORT int zlink_ctx_get(void *context_, zlink_ctx_option_t option_, zlink_config_result_t *error_out_);

Context 옵션의 현재 값을 가져온다. ZLINK_SOCKET_LIMITZLINK_MSG_T_SIZE 같은 읽기 전용 옵션을 포함하여 언제든지 context 구성을 검사하는 데 사용할 수 있다. 실패 시 *error_out_에 설정 결과(zlink_config_result_t)가 기록되고, 성공 시 옵션 값이 기본 반환값으로 반환된다. error_out_은 선택 사항이다 — NULL을 전달하면 실패 시 결과 코드는 기록되지 않고 -1 반환과 errno 설정만 관찰된다.

반환값: 성공 시 옵션 값, 실패 시 -1이며 *error_out_zlink_config_result_t가 기록된다. zlink_errno()는 진단용 내부 errno를 그대로 유지한다.

에러: - EINVAL -- 알 수 없는 옵션. - EFAULT -- 유효하지 않은 context 핸들; *error_out_ZLINK_CONFIG_INVALID_HANDLE이 기록된다.

스레드 안전성: 모든 스레드에서 안전하게 호출할 수 있다.

참고: zlink_ctx_set, zlink_ctx_get_data

6. 구현 및 contract test 검증 요구

공개 표면(zlink_ctx_* 함수, 옵션 set·get, 반환값·errno)만으로 다음을 확인한다. 각 항목은 unit test 하나로 이어진다.

수명 - zlink_ctx_new는 성공 시 non-NULL 핸들을, 실패 시 NULL과 설정된 errno를 반환한다. - zlink_ctx_shutdown을 호출하면 그 context에 속한 socket의 blocking 작업이 즉시 ETERM으로 반환된다. - zlink_ctx_term은 context당 한 번 성공하고, 그 안의 모든 socket이 닫힐 때까지 blocking될 수 있다. - 유효하지 않은 context 핸들로 zlink_ctx_term·zlink_ctx_shutdown을 호출하면 EFAULT다. - signal로 zlink_ctx_term이 중단되면 EINTR이며 재시도할 수 있다.

옵션 - zlink_ctx_set에 알 수 없는 옵션이나 유효하지 않은 값을 주면 EINVAL, 유효하지 않은 핸들이면 EFAULT(ZLINK_CONFIG_INVALID_HANDLE)다. - ZLINK_THREAD_PRIORITY는 고유 값 22로 설정·조회하고 ZLINK_SOCKET_LIMIT3의 읽기 전용 계약에 영향을 주지 않는다. - 세 Auto HWM byte 옵션을 zlink_ctx_set으로 설정하려 하면 EINVAL이다(설정은 zlink_ctx_set_data만 허용). - Auto HWM byte 옵션을 zlink_ctx_get_data로 정확히 sizeof(uint64_t)가 아닌 크기로 조회하면 EINVAL이고 필요한 크기를 *optvallen_에 기록한다. - enum에 없는 context 옵션 값을 zlink_ctx_set_data로 쓰면 ZLINK_CONFIG_INVALID_ARGUMENT다. - ZLINK_THREAD_NAME_PREFIXzlink_ctx_get_data로 저장된 prefix 길이보다 작은 용량으로 조회하면 EINVAL이고 필요한 길이를 *optvallen_에 기록한다.

스레드 안전성 - 모든 zlink_ctx_* 함수는 여러 thread에서 동시에 호출해도 안전하다. zlink_ctx_term만 context당 한 번으로 제한한다.

Auto HWM budget과 admission의 검증은 Auto HWM가 소유한다.

Core 스펙 목차 | 이전: 공개 계약 관리 | 다음: Message