Skip to main content

jetstream-api

Python으로 작성된 ILink 클라이언트 API입니다.

시스템 요구 사항

시스템에 python 13 이상, pip가 설치되어 있어야 합니다.

설치 방법

pip install jetstream-api

0.2.0 신규 - pub/sub 토픽

큐에 더해 pub/sub 토픽을 지원합니다. 발행된 메시지는 retention 정책이 지울 때까지 보존되어 모든 구독자에게 각자의 커서로 전달됩니다(팬아웃). 큐와 달리 소비해도 사라지지 않습니다.

엔진 v7.1.1 rev 3265 이상이 필요합니다.

구독

from ilink.qmgr import ILQmgr
from ilink.topic import ILTopic, ILSubscribeOptions

qmgr = ILQmgr()
qmgr.connect("127.0.0.1", 19999, "order-svc", True)

topic = qmgr.access_topic("ORDER.EVENT")
sub = topic.subscribe("settlement", ILSubscribeOptions()
                      .start_mode(ILTopic.START_EARLIEST)
                      .commit_mode(ILTopic.COMMIT_MANUAL))

for msg in sub.read_batch(100, 3000):
    print(msg.get_offset(), msg.get_key(), msg.get_data_string())
    sub.commit(msg)

콜백(push)으로 받을 수도 있습니다.

sub.listen(lambda m: print(m.get_data_string()),
           lambda e: print("error:", e))
...
sub.stop_listening()

발행

발행은 producer 단일 경로입니다. 동기 발행은 send().get()을 씁니다.

from ilink.producer import ILProducerConfig, ILProducerRecord

prod = qmgr.create_producer(ILProducerConfig())
meta = prod.send(ILProducerRecord("ORDER.EVENT", "k1", b"payload",
                                  properties={"trace-id": "abc"})).get()
print(meta.get_partition(), meta.get_offset())
prod.close()

와일드카드(패턴) 구독

패턴에 맞는 여러 토픽을 한꺼번에 구독합니다.

pat = qmgr.access_pattern("ORDER.*")
print(pat.resolve())                    # 지금 매칭되는 토픽 (구독 안 함)

ps = pat.subscribe("audit")
m = ps.read(3000)
print(m.get_topic_name(), m.get_data_string())

*는 구분자 .를 포함해 매칭합니다. ORDER.*는 ORDER.KR뿐 아니라 ORDER.KR.SUB도 잡습니다. 정규식이 아니라 글로브입니다. .은 리터럴이라 ORDER.*는 ORDERING을 잡지 않습니다.

토픽 관리

토픽 생성/삭제/속성변경은 관리 표면 전용입니다.

from ilink.admin import ILAdminService

svc = ILAdminService(); svc.connect("127.0.0.1", 9998)
adm = svc.accessAdminQmgr("QMGR1")
adm.createTopic("ORDER.EVENT", "partitions=3")
print(adm.getTopicList())

0.2.0 신규 - 클러스터(HA) 페일오버

클러스터 큐 관리자에 접속하면 후보 주소를 캐싱해 두었다가, 리더가 바뀌어도 따라갑니다.

qmgr.connect("10.0.0.1", 5000, "APP", True)   # 주소 하나면 됩니다
print(qmgr.get_cluster_addresses())           # ['10.0.0.1:5000', '10.0.0.2:5000']
qmgr.reconnect()                              # 새 리더를 찾아 재접속

# 첫 접속 시점의 장애까지 대비하려면 목록으로 (포트 인자 없음)
qmgr.connect("10.0.0.1:5000,10.0.0.2:5000", "APP", True)

접속에 성공하면 핸드셰이크 직후 나머지 노드 주소를 서버에서 받아 캐싱하므로 주소는 하나만 주면 됩니다. 목록은 첫 접속 시점의 장애까지 대비할 때 씁니다.

0.4.4 변경 - 자동 재접속은 옵션이 아니라 기본 동작

캐싱된 endpoint 목록이 있으면(= 클러스터) 통신 장애로 실패한 put/get 을 페일오버 재접속 후 한 번 자동 재시도합니다. set_auto_reconnect() 는 더 이상 필요 없으며, 불러도 무시됩니다(기존 코드 호환용으로만 남겨 두었습니다).

상황 동작
미커밋 트랜잭션 있음 예외를 올립니다. 앱이 reconnect() 후 트랜잭션을 처음부터 다시 수행
미커밋 트랜잭션 없음 (auto-commit 포함) 내부에서 재접속 후 1회 재시도
endpoint 목록 없음 (비클러스터/구엔진) 예외를 올립니다 - 갈 곳이 없습니다

재시도는 at-least-once 입니다. 서버가 처리한 뒤 응답이 유실된 시점에 재시도하면 중복 put 이 생길 수 있습니다. 멱등하지 않은 처리라면 메시지 ID 로 중복을 걸러야 합니다. 미커밋 트랜잭션이 없을 때만 재시도하므로 트랜잭션 유실은 없습니다.

0.4.0 신규 - 관리 연결 하나로 pub/sub

ILAdminService(관리 포트, 보통 9998) 연결만으로 토픽 발행·구독이 가능합니다. 큐 관리자 리스너 포트에 따로 붙지 않아도 되므로, 방화벽이 관리 포트만 열린 환경에서 쓸 수 있습니다.

엔진 v7.0.1 rev 3295 이상이 필요합니다.

from ilink.admin import ILAdminService
from ilink.exception import ILNoMsgException
from ilink.topic import ILSubscribeOptions, ILTopic

svc = ILAdminService()
svc.connect("127.0.0.1", 9998, "admin-app")
aq = svc.accessAdminQmgr("QM1")

# 발행 - (offset, timestamp, partition)
off, ts, part = aq.publish("ORDER.EVENT", b"payload", key="order-1")

# 구독
topic = aq.accessTopic("ORDER.EVENT")
sub = topic.subscribe("audit", ILSubscribeOptions()
                      .startMode(ILTopic.START_EARLIEST)
                      .commitMode(ILTopic.COMMIT_MANUAL))
try:
    while True:
        try:
            msg = sub.read(3000)
        except ILNoMsgException:
            break
        print(msg.get_offset(), msg.get_key(), msg.get_data_string())
        sub.commit(msg)
finally:
    sub.close()

패턴(와일드카드) 구독도 같은 연결로 됩니다.

ps = aq.accessPattern("ORDER.*").subscribe("audit")

제약: 관리 연결에는 배치가 없어 레코드 한 건에 한 번 왕복합니다. 멱등 발행도 지원되지 않습니다(acks=1 고정). 대량 처리나 중복 제거가 필요하면 리스너 포트에 ILQmgr 로 붙어 ILTopicProducer 를 쓰세요.

0.3.0 신규 - 허브-스포크 연결 전환 헬퍼

허브에 접속해 스포크를 찾고 연결을 전환하는 세 단계를 한 번에 처리하는 connectToSpoke()가 추가되었습니다. Java API에도 같은 이름으로 있습니다.

from ilink.admin import ILAdminService

for name in ("S48", "S85"):
    svc = ILAdminService.connectToSpoke("10.10.1.95", 9998, "ADMIN", name)
    try:
        print(name, [q.getName() for q in svc.getQmgrList()])
    finally:
        svc.disconnect()

# 키를 이미 알고 있으면 목록 조회를 건너뛴다 (키는 설정 파일에 저장되어 재기동해도 유지)
svc = ILAdminService.connectToSpokeByKey("10.10.1.95", 9998, "ADMIN", spoke_key)

연결 전환 후 그 연결은 해당 스포크에 직접 접속한 것으로 에뮬레이션됩니다. 따라서 전환은 연결당 한 번뿐이고, 다른 스포크로 가려면 새 연결이 필요합니다. connectToSpoke()가 그 반복을 담당합니다. 실패하면 스스로 연결을 닫으므로 소켓이 새지 않습니다.

TCP 연결 방향이 스포크 → 허브 한 방향뿐이라 스포크 쪽에 인바운드 포트를 열지 않고도 관리할 수 있습니다. 실측상 릴레이 오버헤드는 없었습니다(getQmgrList() 중앙값 릴레이 18.3ms vs 허브 직결 18.4ms).

0.2.1 신규 - Java API 옵션 표면 일치

발행/구독 옵션이 Java API와 같은 이름의 빌더로 정리되었습니다. 기존 snake 표기 (start_mode / commit_mode / linger_ms ...)도 그대로 쓸 수 있습니다.

from ilink.producer import ILProducerConfig

cfg = (ILProducerConfig()
       .acks(1).lingerMs(5).batchSize(32768)
       .maxRequestSize(1048576)      # 레코드 1건 상한 - 넘으면 send()가 거부
       .bufferMemory(33554432)       # 미전송 누적 상한
       .retries(3).retryBackoffMs(100)
       .deliveryTimeoutMs(120000)    # 재시도를 포함한 완결 시한
       .enableIdempotence(True))     # PID/시퀀스 중복 제거 (acks=1 필요)

prod = qmgr.create_producer(cfg)
print(prod.get_producer_id(), prod.is_connected())

구독 옵션에 리밸런스 리스너/prefetch/수동 파티션이 추가되었고, 파티션을 직접 고르는 assign()이 생겼습니다.

sub = topic.subscribe("app1", ILSubscribeOptions()
                      .startMode(ILTopic.START_EARLIEST)
                      .commitMode(ILTopic.COMMIT_MANUAL)
                      .expiryMs(600000)          # 멤버 유휴 만료 10분
                      .prefetch(100)
                      .listener(on_rebalance))

sub = topic.assign("app1", [0, 2], ILTopic.START_EARLIEST)   # 수동 파티션 배정

주의 (0.2.0에서 올라올 때): 옵션 값은 이제 게터로 읽습니다. cfg.acks / opt.durable 은 빌더 메서드이므로 값이 필요하면 cfg.get_acks() / opt.is_durable() 을 쓰세요. cfg.acks = 0 같은 직접 대입은 그대로 동작합니다. 같은 이유로 ILClusterProperty.isAutoStart 와 ILSpokeProperty.isRunning 도 Java처럼 메서드가 되었습니다 (prop.isAutoStart()).

개발자 가이드 문서

공개 API 779개 전부에 한국어 docstring이 붙어 있습니다. 편집기에서 함수 위에 마우스를 올리거나 help()로 파라미터 타입·기본값·허용값·예외를 바로 확인할 수 있습니다.

help(qmgr.access_queue)
help(ILAdminQmgr.getStatSeries)

값 객체(ILQueueProperty 등)는 필드 목록이 클래스 docstring에 정리되어 있습니다. getX() / setX() 접근자는 필드 이름에서 자동으로 만들어지므로, 필드 목록이 곧 접근자 목록입니다.

help(ILQueueProperty)      # 필드 이름 / 타입 / 기본값 / 의미

Release files for jetstream-api 0.4.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jetstream-api 0.4.4
File Size Uploaded
jetstream_api-0.4.4.tar.gz 198.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jetstream-api 0.4.4
File Interpreter ABI Platform
jetstream_api-0.4.4-py3-none-any.whl Python 3 none any Details

Total release size: 400.8 kB

Release files / jetstream_api-0.4.4.tar.gz

Download URL jetstream_api-0.4.4.tar.gz
Size 198.5 kB
Tags Source
SHA-256 checksum
How to use checksums
362cef080c50f8377bbd87b739805e596319538e5e79a27bf0419d824717c084
BLAKE2b-256 checksum
How to use checksums
3ecd52a6afd97cfc6e47174e49c7bfba4f9580bae7a470e920a55da1468b5110
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.4

Release files / jetstream_api-0.4.4-py3-none-any.whl

Download URL jetstream_api-0.4.4-py3-none-any.whl
Size 202.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
431a266ca56a3eb4ce38360b2e3b94ee9ca61ab54d5c2a9b252b989eb0e57428
BLAKE2b-256 checksum
How to use checksums
a824e6e840afc4c576e6f9be249ac9b22fd03763f6d6c4be31040eb34389e88e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.4

Release history Release notifications | RSS feed

0.17.0

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.11

2 release files

0.6.10

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.5

2 release files

This release

0.4.4 This release

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page