콘텐츠로 이동

한국어 | English

레퍼런스 목차

04. Eventing

이 category는 socket monitoring, 재사용 가능한 poller, standalone timer를 다룬다 — 각각 SocketMonitor::open(...), Poller::new(), Timer::new(). Timer는 별도 timer 모듈이 아니라 이 category의 poller.rs에(Poller와 나란히) 선언돼 있다. 정확한 signature는 contracts/eventing/가 소유한다.


SocketMonitor

socket의 connection lifecycle event를 관찰하고 현재 상태를 읽는다.

let mut monitor = SocketMonitor::open(&socket)?;
let event = monitor.recv()?;
println!("{:?} {}", event.event, event.remote_addr);
let status = monitor.status()?;

Options.

Member 의미
open(socket: &dyn Monitorable) -> Result<Self, ConfigError> event-mask 인자를 받지 않으며, 자신의 doc comment에 따르면 항상 모든 event를 구독한다("Open a socket monitor for all events")
open_with_options(socket, SocketMonitorOpenOptions) -> Result<Self, ConfigError> 명시적 event mask와 monitor byte HWM으로 연다
recv(&self) -> Result<MonitorEvent, RecvError> 다음 event를 blocking으로 가져옴
recv_with_flags(&self, flags: RecvFlags) -> Result<Option<MonitorEvent>, RecvError> non-blocking 변형, 대기 중인 게 없으면 Ok(None)
status() 시점 스냅샷 MonitorStatus를 반환
close(&mut self) -> Result<(), CloseError> monitor를 닫음

Completion result. 모든 member는 동기다. Monitorable은 모든 내장 socket type이 구현하는 sealed marker trait다 — crate 사용자는 custom 타입에 대해 이걸 구현할 수 없다.

선택 기준. caller-driven pull loop에는 recv/recv_with_flags를 쓰고 시점 스냅샷에는 status()를 쓴다. Monitor 전달에는 등록형 callback이 없다.


SocketMonitorEventMask(monitor filter option)

monitor를 event의 부분집합에 구독시키는 typed bitmask다. SocketMonitor::open()은 전체 event를 선택하고, open_with_options(socket, SocketMonitorOpenOptions { events, monitor_hwm_bytes })는 명시한 mask와 byte HWM을 적용한다.

Options. 감싸인 u32 필드가 private이라 사용자는 명명된 mask를 BitOr/BitOrAssign으로 결합한다.

Member 의미
ALL 0x7FFFF
CONNECTION_READY 0x1000
SEND_FLOW_PAUSED / SEND_FLOW_RESUMED / FLOW_STATE_STALE paired DEALER/ROUTER flow-state transition
bits() raw 값을 읽음
MONITOR_EVENT_ALL / MONITOR_EVENT_CONNECTION_READY 같은 두 상수의 최상위 편의 alias

Completion result. 해당 없음 — 순수 값 타입.

선택 기준. 전체 event에는 open()을 쓰고 subscription 또는 monitor queue byte HWM을 명시해야 할 때는 open_with_options()를 쓴다.


MonitorEvent

monitor가 보고하는 socket connection-lifecycle event 하나.

if event.is_connected() { /* ... */ }

Options. 편의 predicate 메서드는 전체 lifecycle event 집합 중 일부만 다룬다 — ConnectDelayed, ConnectRetried, BindFailed, AcceptFailed, CloseFailed, MonitorStopped, HandshakeFailedNoDetail, HandshakeFailedProtocol, HandshakeFailedAuth, PeerWeightChanged엔 predicate가 없다 — 이들 중 어느 것도 caller가 대응하는 raw mask 값에 대해 event.0을 직접 bit-test해야 한다.

Field 타입 의미
event MonitorEventType, u64를 감싸는 newtype — 명명된 variant를 가진 enum이 아님 lifecycle event의 종류
value u32 event별 값
routing_id Option<RoutingId> event가 제공할 때만 존재하는 peer routing id
local_addr / remote_addr String event에 결부된 local/remote 주소
is_connected() / is_disconnected() / is_listening() / is_accepted() / is_closed() / is_connection_ready() bool 해당 event 종류에 대한 predicate

Completion result. 해당 없음 — monitor가 전달하는 불변 값.

선택 기준. 다루는 6개 lifecycle transition엔 명명된 is_* predicate를 쓴다. 그 외 event 종류는 event.0을 문서화된 bit 값과 직접 비교한다(전체 mask 표는 core의 Errors/Eventing 스펙 참고).


MonitorStatus

SocketMonitor::status()/snapshot()이 반환하는, monitored entity의 상태와 auto-high-water-mark telemetry 시점 스냅샷. 순수 public-field struct다.

Options. 인자 없음 — 모든 필드가 public이다.

그룹 필드
ABI identity abi_version, struct_size(u32)
Source/state source_kind(MonitorSourceKind: Socket만), state_flags/detail_flags(u32 비트마스크), is_ready()/is_closed()(계산 method)
Pending count snd_pending_msgs, rcv_pending_msgs(u64)
Auto-HWM 설정 auto_hwm_enabled(bool), auto_hwm_profile/auto_hwm_role/auto_hwm_policy_class(u32), auto_hwm_unit_budget_bytes/auto_hwm_socket_message_slots(u64), auto_hwm_size_cap(u32)
Connection bucket auto_hwm_connection_bucket_enabled(bool), auto_hwm_connection_bucket_count/_index/_hwm_4k(u32, bucket이 없으면 index는 u32::MAX), auto_hwm_connection_bucket_hysteresis_retained(bool)
Auto-HWM plan(byte) auto_hwm_effective_message_bytes, auto_hwm_planned_sndhwm_bytes/_rcvhwm_bytes, auto_hwm_applied_sndhwm_bytes/_rcvhwm_bytes(u64), auto_hwm_effective_sndbuf/_rcvbuf(i32)
Auto-HWM recalc auto_hwm_last_recalc_ms(u64), auto_hwm_last_recalc_reason(AutoHwmRecalcReason, Core category), auto_hwm_send_blocked_ratio_ppm(u32)
Auto-HWM deferred shrink auto_hwm_deferred_sndhwm_bytes/_rcvhwm_bytes(u64, 대응하는 auto_hwm_deferred_sndhwm_valid/_rcvhwm_valid bool이 true일 때만 유효)
In-flight/과금 snd_bytes_in_flight, rcv_bytes_in_flight, minimum_core_message_charge_bytes, oversize_message_admission_count, oversize_message_admission_max_bytes(u64)

Completion result. 해당 없음 — 순수 public 필드에 더해 계산 method is_ready()/is_closed() 둘.

선택 기준. state_flags를 직접 디코딩하는 대신 is_ready()/is_closed()를 호출한다. socket의 실제 send/receive HWM이 설정한 CommonSocketOptions 값(Sockets category)과 다른 이유를 진단할 땐 connection-bucket과 auto-HWM-plan 필드를 쓴다.


Poller

socket, file descriptor, timer를 하나의 재사용 가능한 wait로 multiplex한다.

let poller = Poller::new()?;
poller.add_socket(&dealer, POLLIN, 1)?;
poller.add_timer(&timer, 2)?;
let mut events = vec![PollEvent::default(); 8];
let ready = poller.wait(&mut events, 1000)?;

Options. Pollable은 모든 내장 socket type이 구현하는 sealed marker trait다 — crate 사용자는 custom 타입에 대해 이걸 구현할 수 없다.

Member 의미
new() -> Result<Self, ConfigError> poller를 생성
add_socket(&self, socket: &dyn Pollable, events: i16, slot: usize) -> Result<(), ConfigError> socket을 등록; slot은 대응하는 poll 결과로 그대로 되돌아오는 caller token
add_fd(&self, fd: RawFd, events: i16, slot: usize) raw file descriptor를 등록, 같은 형태
add_timer(&self, timer: &Timer, slot: usize) timer를 socket/fd와 함께 multiplex하도록 등록
modify_socket(&self, socket, events) / modify_fd(&self, fd, events) 이미 등록된 socket/fd의 감시 event를 교체
remove_socket(&self, socket) / remove_fd(&self, fd) / remove_timer(&self, timer: &Timer) source 등록을 해제
wait(&self, events: &mut [PollEvent], timeout_ms: i64) -> Result<usize, RecvError> timeout_ms까지 block하며 events.len()까지 결과를 그 자리에 씀; 음수 timeout은 무기한 block
size(&self) -> i32 현재 등록된 source 개수

Completion result. 등록/제거 member는 Result<(), ConfigError>를 반환한다. waitResult<usize, RecvError>(준비된 개수)를 반환하며, events.len()까지 결과를 그 자리에 쓴다. modify_socketPOLLCOMPLETION을 원자적으로 추가·제거하며 native registration 변경과 함께 completion-drain owner를 이전한다. Public poller가 그 bit를 소유하는 동안 owner는 wait()를 계속 호출해 completion을 drain·settle해야 한다. 동시에 blocking terminal이 필요하면 다른 execution context에서 수행한다.

선택 기준. 서비스 수명 전체에서 poller 하나를 쓴다. wait 호출마다 할당하는 대신 Vec<PollEvent> buffer 하나를 재사용한다.


PollEvent / PollItem

PollEventPoller::wait가 보고하는 준비된 source 하나다. PollItemPoller 대신 standalone poll(...) 자유 함수(Core category)가 쓰는 raw poll descriptor다.

Options — PollEvent(Default 구현, 모든 필드 public).

Field 타입 의미
source_kind PollSourceKind: Socket/Fd/Timer source가 socket·file descriptor·timer 중 무엇인지
fd RawFd file descriptor, Fd kind source에서만 채워짐
slot usize 등록 시 제공한 caller token
revents i16 POLL* 상수의 mask
is_readable() / is_writable() bool POLLIN/POLLOUT에 대한 편의 bit-test

Options — PollItem(모든 필드 public).

Field 타입 의미
fd RawFd 이 item이 감시하는 file descriptor
events / revents i16 감시할/반환된 poll-event bitmask

Completion result. 해당 없음 — 순수 값 타입.

선택 기준. PollEvent::source_kind/slot으로 분기해 각 Poller::wait 결과를 대응하는 socket·descriptor·timer로 연결한다. PollItemPoller가 아니라 standalone poll(...) 함수와만 쓴다.


Timer

interval마다 fire하며 poll하거나 await할 수 있는 timer로, Poller와 독립적으로 생성되지만 Poller::add_timer로 등록할 수 있다.

let mut timer = Timer::new()?;
timer.start(1_000_000_000, 0)?; // 나노초 단위 interval
let count = timer.recv()?;

Options.

Member 의미
new() -> Result<Self, ConfigError> timer를 생성
start(&self, interval_ns: u64, repeat_count: u64) -> Result<(), ConfigError> interval_ns마다 fire를 시작; interval이 나노초 단위다, Duration/밀리초 기반 start를 쓰는 다른 모든 언어와 다르다; repeat_count == 0은 무제한
stop(&self) -> Result<(), ConfigError> fire를 멈춤; start로 재시작 가능
recv(&self) -> Result<Option<u64>, RecvError> 누적 fire count, 대기 중인 게 없으면 Ok(None)

Completion result. 모든 member는 동기다.

선택 기준. 만료를 pull하려면 recv를, socket과 함께 하나의 wait에서 multiplex하려면 Poller::add_timer로 등록한다. Timer 전달에는 등록형 callback이 없다.


Eventing 상수

상수 사용처
POLLIN / POLLOUT / POLLCOMPLETION(i16) Poller::add_socket/modify_socket/add_fd/modify_fd, PollItem.events/.revents 1, 2, 32이 binding의 public contract엔 POLLERR/POLLPRI 상수가 없다, 지금까지 다룬 다른 모든 언어와 다르다
MonitorSourceKind MonitorStatus::source_kind Socket
PollSourceKind PollEvent::source_kind Socket, Fd, Timer

contracts/eventing/Rust 바인딩 스펙에서 전체 근거를 확인한다.