콘텐츠로 이동

01. Host lifecycle

레퍼런스 목차

이 category는 Spring Boot host 등록 진입점과 ZLinkFrameworkRuntime이 제공하는 진입점을 다룬다. 정확한 signature는 Java 공통 runtime exact interfaceJava 구성과 host exact interface가 소유한다.


@EnableZLinkFramework + ZLinkFrameworkConfigurer (구성 시점)

Framework root를 Spring application context에 한 번 등록한다. 다른 모든 항목의 전제 조건이다.

@Configuration
@EnableZLinkFramework
public class GameFrameworkConfig {

    @Bean
    ZLinkFrameworkConfigurer gameConfigurer() {
        return options -> {
            ZLinkMeshNodeBuilder play = options.addRouteMesh("play")
                .listen(5501)
                .setRoutingIdPrefix("play")
                .setPlacementWeight(100);
        };
    }
}

옵션. 이 호출에는 다음 modifier가 붙는다.

Modifier 기본값 의미
@EnableZLinkFramework 필수 Spring starter의 auto-configuration을 활성화한다
ZLinkFrameworkConfigurer bean (configure(ZLinkFrameworkOptions)) 필수 topology, handler, Location Store 등 모든 등록의 진입점이다. 여러 bean을 등록하면 모두 순서대로 적용된다

완료 결과. 반환값 없이 동기로 등록된다. Spring context 초기화(bean 생성) 시점에 구성을 검증하고, 실패하면 ZLinkConfigurationException으로 startup 자체를 실패시킨다 — 잘못된 구성이 message 처리 중에 처음 나타나지 않는다.

선택 기준. 모든 host가 정확히 한 번(하나 이상의 configurer bean으로) 등록한다. ZLinkFrameworkOptions의 topology·handler 등록 세부는 topology-discovery category를 참고한다. Application은 ZLinkFrameworkRuntime을 직접 생성·시작하지 않는다 — Spring starter가 SmartLifecycle.start()로 소유한다.


relocate

현재 host가 들고 있는 stateful object(User Spot·Actor)를 다른 eligible node로 이전한다. 계획된 점검이나 rolling update 전에 호출한다.

ZLinkFrameworkRelocationOptions options = new ZLinkFrameworkRelocationOptions(
    ZLinkFrameworkRelocationMode.ROLLING_UPDATE,
    2L,
    Duration.ofMinutes(5));

ZLinkFrameworkRelocationResult result = runtime.relocate(options)
    .toCompletableFuture().get();

if (result.outcome() == ZLinkFrameworkRelocationOutcome.RELOCATED) {
    runtime.shutdown().toCompletableFuture().get();
}

옵션. ZLinkFrameworkRelocationOptions의 component는 다음과 같다.

Component 기본값 의미
mode 필수 PLANNED_MAINTENANCE(source와 같은 application version만 target) 또는 ROLLING_UPDATE(지정한 version만 target)
targetApplicationVersion PLANNED_MAINTENANCE에서는 null(source 값 사용), ROLLING_UPDATE에서는 필수(source보다 커야 함) 목표 application version. 조합이 맞지 않으면 시작 전 IllegalArgumentException으로 거부한다
deadline null이면 Framework 기본 deadline eligible target 수렴을 기다리는 상한

완료 결과. ZLinkFrameworkRelocationResult.outcome()RELOCATED면 모든 object 이전이 끝나고 host는 RELOCATED 상태가 된다(새 operation은 받지 않지만 infrastructure는 유지한다). BLOCKEDreason()TARGET_UNAVAILABLE·STORE_UNAVAILABLE·DEADLINE_EXCEEDED 등이 담긴다. 각 호출은 shared operation 결과를 따르는 전용 CompletableFuture view를 반환한다 — toCompletableFuture().cancel(...)은 그 waiter만 해제하며 host operation 자체는 계속 진행된다.

선택 기준. 배포 전 무중단 이전이 필요할 때 쓴다. 이전 없이 바로 종료하려면 shutdown을 직접 호출한다. 같은 mode·target version으로 중복 호출하면 진행 중인 operation에 합류하고, 다른 값으로 호출하면 BLOCKED/OPERATION_IN_PROGRESS로 완료한다.


shutdown

Host를 종료한다. Relocation을 시작하지 않는다 — 이전이 필요하면 먼저 relocate를 호출한다.

ZLinkFrameworkTerminationResult result = runtime.shutdown(Duration.ofSeconds(30))
    .toCompletableFuture().get();

옵션. 이 호출에는 다음 modifier가 붙는다.

Modifier 기본값 의미
shutdown() 없음(overload) Framework 기본 deadline 사용
shutdown(Duration deadline) 종료 정리 상한. 초과하면 FORCE_STOPPED로 완료한다

완료 결과. ZLinkFrameworkTerminationResult.outcome()STOPPED(정상 정리) 또는 FORCE_STOPPED(deadline 초과·정리 실패)다. SERVING에서 호출하면 남은 application 처리와 resource를 정리하고, RELOCATED에서 호출하면 infrastructure 연결만 정리한다.

선택 기준. Host를 종료할 때 항상 호출한다. RELOCATING 도중 호출하면 진행 중인 atomic relocation unit의 결과만 확정하고 나머지는 시작하지 않는다 — 그 relocation을 기다리던 호출자는 BLOCKED/SHUTDOWN_REQUESTED를 받는다.


status / observe (읽기·관찰)

Host의 현재 상태를 한 번 읽거나, 상태 변화를 실시간으로 관찰한다.

ZLinkFrameworkRuntimeStatus status = runtime.status();
boolean canAcceptNewOperations = status.isReady() && status.acceptingWork();

runtime.observe().subscribe(new Flow.Subscriber<>() {
    // onNext(observed)에서 observed.status(), observed.loss()를 확인한다
});

옵션. 이 진입점에는 modifier가 없다 — status()는 인자가 없고, observe()Flow.Publisher<ZLinkObservedStatus<ZLinkFrameworkRuntimeStatus>>를 반환한다.

완료 결과. status()는 동기 호출이다. isReady()state() == SERVING일 때만 true이고, acceptingWork()는 새 application operation 수락 여부를 나타낸다 — 두 값이 다를 수 있으므로 둘 다 확인한다. observe()는 terminal 완료 없이 스트리밍하며, ZLinkObservedStatus.loss() (coalescedCount/discardedTerminalCount)로 관찰 유실 여부를 판단한다.

선택 기준. 지금 이 순간의 상태 한 번만 필요할 때 status()를, 상태 전이를 놓치지 않고 계속 받으려면 observe()를 쓴다. Spring Boot Actuator HealthIndicator를 구현할 때도 이 status()를 읽어 Health.up()/Health.outOfService()를 결정한다 — Framework가 별도 health builder를 제공하지 않으므로 이 판단은 application의 HealthIndicator bean이 직접 작성한다.


전체 근거는 Java 공통 runtime exact interfaceJava 구성과 host exact interface를 참고한다.