콘텐츠로 이동

한국어 | English

레퍼런스 목차

04. Eventing

이 category는 socket monitoring, 재사용 가능한 poller, poll-result buffer를 다룬다 — 각각 Socket.monitorOpen(...)(Sockets category)와 createPoller()(Core category)로 생성된다. Timer/AtomicCounter/ Stopwatch/ThreadTimer의 interface가 이 category의 timer.ts 파일에 물리적으로 선언돼 있음에도, 이 레퍼런스 트리가 따르는 언어간 관례에 따라 Core category에 문서화돼 있다. 정확한 signature는 contracts/eventing/가 소유한다.


MonitorSocket

socket의 connection lifecycle event를 관찰하고 현재 상태를 읽는다(이 binding의 contract에선 다른 언어의 SocketMonitor/socket_monitor_t와 달리 MonitorSocket으로 명명됨).

const monitor = socket.monitorOpen([MonitorEventType.Connected]);
const event = monitor.recv(RecvFlags.DontWait);
if (event) logger.info(`${event.event} ${event.remoteAddr}`);
const status = monitor.status();

Options.

Member 의미
recv(flags?: number) 다음 event를 가져옴; MonitorEvent \| null 반환 — non-blocking flag 아래 대기 중인 게 없으면 null
status() 시점 스냅샷 MonitorStatus를 반환
close() monitor를 닫음

Completion result. 모든 member는 동기다.

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


MonitorEvent

monitor가 보고하는 socket connection-lifecycle event 하나. private 생성자를 가진 class다 — instance는 monitor recv operation으로만 생성되며 직접 생성할 수 없다.

Options. 인자 없음 — 직접 생성하지 않고 monitor의 recv로 얻는다.

Field 타입 의미
event MonitorEventType lifecycle event의 종류
value number 에러 코드나 reconnect interval 같은 event별 값
routingId RoutingId \| null event가 제공할 때만 존재하는 peer routing id
localAddr / remoteAddr string event에 결부된 local/remote 주소

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

선택 기준. event로 분기해 특정 lifecycle transition에 반응한다. event별 세부사항(event에 따라 의미가 다름)엔 value를 읽는다.


MonitorStatus

MonitorSocket.status()가 반환하는, socket의 monitored 상태와 auto-high-water-mark telemetry 스냅샷. 순수 읽기 전용 interface다.

Options. 인자 없음 — 모든 member가 readonly property다.

그룹 Member
ABI identity abiVersion, structSize(number)
Source/state sourceKind(MonitorSourceKindValue), stateFlags/detailFlags(number 비트마스크), isReady()(계산 method)
Pending count sndPendingMsgs, rcvPendingMsgs(bigint)
Auto-HWM 설정 autoHwmEnabled(boolean), autoHwmProfile/autoHwmRole/autoHwmPolicyClass(numberAutoHwmProfileValue로 타입 지정되지 않음, ContextOptions.autoHwmProfile과 달리 여기선 raw number), autoHwmUnitBudgetBytes/autoHwmSocketMessageSlots(bigint), autoHwmSizeCap(number)
Connection bucket autoHwmConnectionBucketEnabled(boolean), autoHwmConnectionBucketCount/Index/Hwm4K(number), autoHwmConnectionBucketHysteresisRetained(boolean)
Auto-HWM plan(byte) autoHwmEffectiveMessageBytes, autoHwmPlannedSndHwmBytes/PlannedRcvHwmBytes, autoHwmAppliedSndHwmBytes/AppliedRcvHwmBytes(bigint), autoHwmEffectiveSndBuf/EffectiveRcvBuf(number)
Auto-HWM recalc autoHwmLastRecalcMs(bigint), autoHwmLastRecalcReason(number), autoHwmSendBlockedRatioPpm(number)
Auto-HWM deferred shrink autoHwmDeferredSndHwmBytes/DeferredRcvHwmBytes(bigint, 대응하는 autoHwmDeferredSndHwmValid/DeferredRcvHwmValid boolean이 true일 때만 유효)
In-flight/과금 sndBytesInFlight, rcvBytesInFlight, minimumCoreMessageChargeBytes, oversizeMessageAdmissionCount, oversizeMessageAdmissionMaxBytes(bigint)

Completion result. 모든 property는 불변 스냅샷에 대한 동기 읽기다.

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


Poller

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

const poller = createPoller();
poller.add(dealer, [PollEventFlag.PollIn], 1);
poller.add(timer, 2);
const events = createPollEvents(8);
const ready = poller.wait(events, 1000);

Options.

Member 의미
size 읽기 전용, 현재 등록된 source 개수
add(socket: BaseSocket, events: readonly PollEventFlagValue[], slot: number) socket을 등록; event는 varargs(java)나 결합된 bitmask(dotnet/cpp)가 아니라 readonly 배열 인자로 주어진다
addFd(fd, events, slot) raw file descriptor를 등록, 같은 배열/slot 형태
add(timer: Timer, slot: number) timer를 socket/fd와 함께 multiplex하도록 등록
modify(socket, events) / modifyFd(fd, events) 이미 등록된 socket/fd의 감시 event를 교체
remove(socket) / remove(timer) / removeFd(fd) source 등록을 해제; boolean 반환, 실제로 등록돼 있었으면 true
wait(events: PollEvents, timeoutMs: number) timeoutMs까지 block하며 events를 그 자리에서 채움; 음수 timeout은 무기한 block

Completion result. 등록/제거 member는 동기다. waittimeoutMs까지 block하며, events를 그 자리에서 채우고 준비된 개수를 number로 반환한다. Socket을 PollEventFlag.PollCompletion으로 등록했다면 owner가 wait()를 계속 호출해 binding이 native completion을 drain·settle하게 해야 한다. 두 역할이 모두 필요하면 별도 execution context에서 blocking terminal을 수행한다.

선택 기준. 서비스 수명 전체에서 poller 하나를 쓴다. 감시하는 event만 바뀔 땐 remove + add 대신 modify를 선호한다. wait 호출마다 새로 만드는 대신 PollEvents buffer 하나를 재사용한다.


PollEvents / PollEvent

Poller.wait(...)이 채우는 재사용 가능한 poll 결과 buffer로, createPollEvents(capacity)(Core category)로 생성된다 — java의 PollEvents와 비슷한 설계이며, dotnet의 Span<PollEvent>/cpp의 raw pointer-and-capacity 쌍과 구별된다.

const events = createPollEvents(16);
poller.wait(events, 500);
for (let i = 0; i < events.readyCount; i++) {
  if (events.hasEvent(i, PollEventFlag.PollIn)) { /* ... */ }
}

Options — PollEvents.

Member 의미
capacity 읽기 전용 number, createPollEvents(...)에 넘긴 고정 용량
readyCount 읽기 전용 number, 마지막 wait 이후 몇 개 slot이 준비된 event를 담고 있는지
sourceKind(index) number, 해당 index의 준비된 source 종류
slot(index) number, 그 source 등록 시 넘긴 caller token
revents(index) number, 해당 index의 raw poll-event bitmask
fd(index) number, 해당 index의 file descriptor, FD kind source에서만 채워짐
hasEvent(index, event: PollEventFlagValue) revents(index)에 대한 편의 bit-test, boolean 반환
close() buffer를 해제

Options — PollEvent. 순수 읽기 전용 interface다 — sourceKind, slot, revents, fd(전부 number) — PollEvents와 구별되며, 이 레퍼런스 tier에 문서화된 어떤 진입점으로도 직접 생성되지 않는다(java의 PollEvents.eventAt(index)와 달리, 이 binding의 PollEvents엔 대응하는 materialize 메서드가 선언돼 있지 않다).

Completion result. 모든 PollEvents accessor는 동기다. PollEvent는 자신의 accessor method가 없는 순수 읽기 전용 값 형태다.

선택 기준. revents(index)를 손으로 bit-test하는 대신 hasEvent(index, flag)를 선호한다.


Eventing 상수

상수 사용처
MonitorSourceKind MonitorStatus.sourceKind Socket — 소스 자체 주석에 따르면 "Core raw API는 socket source만 정의한다"
MonitorEventType Socket.monitorOpen(events)(Sockets category), MonitorEvent.event Connected, ConnectDelayed, ConnectRetried, Listening, BindFailed, Accepted, AcceptFailed, Closed, CloseFailed, Disconnected, MonitorStopped, HandshakeFailedNoDetail, ConnectionReady, HandshakeFailedProtocol, HandshakeFailedAuth, PeerWeightChanged — 여기엔 All member가 없다. 대신 Sockets category의 SOCKET_MONITOR_EVENT_ALL 상수를 쓴다

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