jetstream-api 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jetstream_api-0.3.0/jetstream_api.egg-info → jetstream_api-0.4.0}/PKG-INFO +49 -2
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/README.md +48 -1
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/__init__.py +1 -1
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/admin.py +166 -39
- jetstream_api-0.4.0/ilink/admintopic.py +617 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/common.py +9 -7
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/connectivity.py +12 -12
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/exception.py +1 -1
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/msg.py +12 -13
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/pattern.py +10 -15
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/producer.py +18 -26
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/properties.py +11 -13
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/qmgr.py +34 -34
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/topic.py +30 -34
- {jetstream_api-0.3.0 → jetstream_api-0.4.0/jetstream_api.egg-info}/PKG-INFO +49 -2
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/jetstream_api.egg-info/SOURCES.txt +1 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/pyproject.toml +1 -1
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/LICENSE.txt +0 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/py.typed +0 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/ilink/util.py +0 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/jetstream_api.egg-info/dependency_links.txt +0 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/jetstream_api.egg-info/requires.txt +0 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/jetstream_api.egg-info/top_level.txt +0 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/setup.cfg +0 -0
- {jetstream_api-0.3.0 → jetstream_api-0.4.0}/tests/test_example.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jetstream-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Python client API for iLink M.O.M. (Message Oriented Middleware)
|
|
5
5
|
Author: snowjeans
|
|
6
6
|
License: Boost Software License - Version 1.0 - August 17th, 2003
|
|
@@ -147,6 +147,53 @@ qmgr.reconnect() # 새 리더를 찾아 재접속
|
|
|
147
147
|
> (`reconnect()` 직접 호출은 가능합니다). auto-commit 세션도 응답 유실 시점의 재시도로
|
|
148
148
|
> **중복 put이 발생할 수 있습니다.**
|
|
149
149
|
|
|
150
|
+
## 0.4.0 신규 - 관리 연결 하나로 pub/sub
|
|
151
|
+
|
|
152
|
+
`ILAdminService`(관리 포트, 보통 9998) 연결만으로 토픽 발행·구독이 가능합니다.
|
|
153
|
+
큐 관리자 리스너 포트에 따로 붙지 않아도 되므로, **방화벽이 관리 포트만 열린 환경**에서
|
|
154
|
+
쓸 수 있습니다.
|
|
155
|
+
|
|
156
|
+
> 엔진 v7.0.1 rev 3295 이상이 필요합니다.
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from ilink.admin import ILAdminService
|
|
160
|
+
from ilink.exception import ILNoMsgException
|
|
161
|
+
from ilink.topic import ILSubscribeOptions, ILTopic
|
|
162
|
+
|
|
163
|
+
svc = ILAdminService()
|
|
164
|
+
svc.connect("127.0.0.1", 9998, "admin-app")
|
|
165
|
+
aq = svc.accessAdminQmgr("QM1")
|
|
166
|
+
|
|
167
|
+
# 발행 - (offset, timestamp, partition)
|
|
168
|
+
off, ts, part = aq.publish("ORDER.EVENT", b"payload", key="order-1")
|
|
169
|
+
|
|
170
|
+
# 구독
|
|
171
|
+
topic = aq.accessTopic("ORDER.EVENT")
|
|
172
|
+
sub = topic.subscribe("audit", ILSubscribeOptions()
|
|
173
|
+
.startMode(ILTopic.START_EARLIEST)
|
|
174
|
+
.commitMode(ILTopic.COMMIT_MANUAL))
|
|
175
|
+
try:
|
|
176
|
+
while True:
|
|
177
|
+
try:
|
|
178
|
+
msg = sub.read(3000)
|
|
179
|
+
except ILNoMsgException:
|
|
180
|
+
break
|
|
181
|
+
print(msg.get_offset(), msg.get_key(), msg.get_data_string())
|
|
182
|
+
sub.commit(msg)
|
|
183
|
+
finally:
|
|
184
|
+
sub.close()
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
패턴(와일드카드) 구독도 같은 연결로 됩니다.
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
ps = aq.accessPattern("ORDER.*").subscribe("audit")
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
> **제약**: 관리 연결에는 배치가 없어 **레코드 한 건에 한 번 왕복**합니다. 멱등 발행도
|
|
194
|
+
> 지원되지 않습니다(acks=1 고정). 대량 처리나 중복 제거가 필요하면 리스너 포트에
|
|
195
|
+
> `ILQmgr` 로 붙어 `ILTopicProducer` 를 쓰세요.
|
|
196
|
+
|
|
150
197
|
## 0.3.0 신규 - 허브-스포크 연결 전환 헬퍼
|
|
151
198
|
|
|
152
199
|
허브에 접속해 스포크를 찾고 연결을 전환하는 세 단계를 한 번에 처리하는
|
|
@@ -218,7 +265,7 @@ sub = topic.assign("app1", [0, 2], ILTopic.START_EARLIEST) # 수동 파티션
|
|
|
218
265
|
|
|
219
266
|
## 개발자 가이드 문서
|
|
220
267
|
|
|
221
|
-
**공개 API
|
|
268
|
+
**공개 API 779개 전부에 한국어 docstring이 붙어 있습니다.** 편집기에서 함수 위에
|
|
222
269
|
마우스를 올리거나 `help()`로 파라미터 타입·기본값·허용값·예외를 바로 확인할 수 있습니다.
|
|
223
270
|
|
|
224
271
|
```python
|
|
@@ -101,6 +101,53 @@ qmgr.reconnect() # 새 리더를 찾아 재접속
|
|
|
101
101
|
> (`reconnect()` 직접 호출은 가능합니다). auto-commit 세션도 응답 유실 시점의 재시도로
|
|
102
102
|
> **중복 put이 발생할 수 있습니다.**
|
|
103
103
|
|
|
104
|
+
## 0.4.0 신규 - 관리 연결 하나로 pub/sub
|
|
105
|
+
|
|
106
|
+
`ILAdminService`(관리 포트, 보통 9998) 연결만으로 토픽 발행·구독이 가능합니다.
|
|
107
|
+
큐 관리자 리스너 포트에 따로 붙지 않아도 되므로, **방화벽이 관리 포트만 열린 환경**에서
|
|
108
|
+
쓸 수 있습니다.
|
|
109
|
+
|
|
110
|
+
> 엔진 v7.0.1 rev 3295 이상이 필요합니다.
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from ilink.admin import ILAdminService
|
|
114
|
+
from ilink.exception import ILNoMsgException
|
|
115
|
+
from ilink.topic import ILSubscribeOptions, ILTopic
|
|
116
|
+
|
|
117
|
+
svc = ILAdminService()
|
|
118
|
+
svc.connect("127.0.0.1", 9998, "admin-app")
|
|
119
|
+
aq = svc.accessAdminQmgr("QM1")
|
|
120
|
+
|
|
121
|
+
# 발행 - (offset, timestamp, partition)
|
|
122
|
+
off, ts, part = aq.publish("ORDER.EVENT", b"payload", key="order-1")
|
|
123
|
+
|
|
124
|
+
# 구독
|
|
125
|
+
topic = aq.accessTopic("ORDER.EVENT")
|
|
126
|
+
sub = topic.subscribe("audit", ILSubscribeOptions()
|
|
127
|
+
.startMode(ILTopic.START_EARLIEST)
|
|
128
|
+
.commitMode(ILTopic.COMMIT_MANUAL))
|
|
129
|
+
try:
|
|
130
|
+
while True:
|
|
131
|
+
try:
|
|
132
|
+
msg = sub.read(3000)
|
|
133
|
+
except ILNoMsgException:
|
|
134
|
+
break
|
|
135
|
+
print(msg.get_offset(), msg.get_key(), msg.get_data_string())
|
|
136
|
+
sub.commit(msg)
|
|
137
|
+
finally:
|
|
138
|
+
sub.close()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
패턴(와일드카드) 구독도 같은 연결로 됩니다.
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
ps = aq.accessPattern("ORDER.*").subscribe("audit")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
> **제약**: 관리 연결에는 배치가 없어 **레코드 한 건에 한 번 왕복**합니다. 멱등 발행도
|
|
148
|
+
> 지원되지 않습니다(acks=1 고정). 대량 처리나 중복 제거가 필요하면 리스너 포트에
|
|
149
|
+
> `ILQmgr` 로 붙어 `ILTopicProducer` 를 쓰세요.
|
|
150
|
+
|
|
104
151
|
## 0.3.0 신규 - 허브-스포크 연결 전환 헬퍼
|
|
105
152
|
|
|
106
153
|
허브에 접속해 스포크를 찾고 연결을 전환하는 세 단계를 한 번에 처리하는
|
|
@@ -172,7 +219,7 @@ sub = topic.assign("app1", [0, 2], ILTopic.START_EARLIEST) # 수동 파티션
|
|
|
172
219
|
|
|
173
220
|
## 개발자 가이드 문서
|
|
174
221
|
|
|
175
|
-
**공개 API
|
|
222
|
+
**공개 API 779개 전부에 한국어 docstring이 붙어 있습니다.** 편집기에서 함수 위에
|
|
176
223
|
마우스를 올리거나 `help()`로 파라미터 타입·기본값·허용값·예외를 바로 확인할 수 있습니다.
|
|
177
224
|
|
|
178
225
|
```python
|
|
@@ -1154,7 +1154,7 @@ class ILAdminService:
|
|
|
1154
1154
|
|
|
1155
1155
|
Warning:
|
|
1156
1156
|
**세션 회수는 비동기다.** 클라이언트가 :meth:`disconnect` 로 정상 종료해도
|
|
1157
|
-
그 세션이 목록에서 곧바로 사라지지 않는다 - 실측(
|
|
1157
|
+
그 세션이 목록에서 곧바로 사라지지 않는다 - 실측(127.0.0.1 허브) 약 **1초**
|
|
1158
1158
|
동안 ``getStatus()`` 가 여전히 ``1``, ``getDestroyedTime()`` 이 ``-1`` 인
|
|
1159
1159
|
채로 남아 있다가 사라진다. 끊긴 것을 확인하려면 **한 번 조회로 단정하지 말고
|
|
1160
1160
|
잠시 기다렸다 다시 조회하라.**
|
|
@@ -1459,13 +1459,13 @@ class ILAdminService:
|
|
|
1459
1459
|
조회하거나 지울 수 없다는 뜻이다.
|
|
1460
1460
|
|
|
1461
1461
|
Note:
|
|
1462
|
-
실측(
|
|
1462
|
+
실측(127.0.0.1 허브, 스포크 2대): 전환 자체는 **20~45ms**, 전환 뒤 요청의
|
|
1463
1463
|
릴레이 오버헤드는 **측정되지 않는 수준**이다(``getQmgrList`` 중앙값 릴레이
|
|
1464
1464
|
18.3ms vs 허브 직결 18.4ms). ``timeoutSec`` 은 0 이나 1 을 줘도 성공했다.
|
|
1465
1465
|
|
|
1466
1466
|
Example::
|
|
1467
1467
|
|
|
1468
|
-
svc.connect("
|
|
1468
|
+
svc.connect("127.0.0.1", 9998, "ADMIN")
|
|
1469
1469
|
for sp in svc.getSpokeList():
|
|
1470
1470
|
if sp.getName() == "S48":
|
|
1471
1471
|
svc.spokeSwitchTo(sp.getKey(), 10)
|
|
@@ -1509,8 +1509,7 @@ class ILAdminService:
|
|
|
1509
1509
|
|
|
1510
1510
|
Raises:
|
|
1511
1511
|
ILOperationException: 그런 이름의 스포크가 없거나 전환이 거절됐을 때.
|
|
1512
|
-
없는 이름이면 ``MIMQE_OBJECT_NOT_FOUND (spoke: 이름)``
|
|
1513
|
-
Java 와 사유 코드를 맞추려고 엔진 관례의 접두사를 쓴다.
|
|
1512
|
+
없는 이름이면 ``MIMQE_OBJECT_NOT_FOUND (spoke: 이름)`` 이다.
|
|
1514
1513
|
ILSessionException: 허브에 접속하지 못했을 때.
|
|
1515
1514
|
ILException: 그 밖의 통신 실패.
|
|
1516
1515
|
|
|
@@ -1525,7 +1524,7 @@ class ILAdminService:
|
|
|
1525
1524
|
Example::
|
|
1526
1525
|
|
|
1527
1526
|
for name in ("S48", "S85"):
|
|
1528
|
-
svc = ILAdminService.connectToSpoke("
|
|
1527
|
+
svc = ILAdminService.connectToSpoke("127.0.0.1", 9998, "ADMIN", name)
|
|
1529
1528
|
try:
|
|
1530
1529
|
print(name, [q.getName() for q in svc.getQmgrList()])
|
|
1531
1530
|
finally:
|
|
@@ -2116,12 +2115,9 @@ class ILAdminQmgr:
|
|
|
2116
2115
|
**트레이스를 켜면 로그가 급격히 늘어난다** - 장애 분석 때만 쓰라.
|
|
2117
2116
|
특정 세션만 보려면 :meth:`setSessionTrace` 가 부담이 적다.
|
|
2118
2117
|
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
뒤집혀 있다** - 성공하면 빈 사유로 예외가 나고, 실패하면 조용히 통과한다.
|
|
2123
|
-
파이썬은 ``MIMQ_SUCCESSFUL_*`` 로 바로잡았다(실서버 확인: 성공 4208 /
|
|
2124
|
-
실패 4209). **Java 쪽도 고쳐야 한다.**
|
|
2118
|
+
Note:
|
|
2119
|
+
성공 판정은 ``MIMQ_SUCCESSFUL_*`` 응답으로 한다(실서버 확인: 성공 4208 /
|
|
2120
|
+
실패 4209).
|
|
2125
2121
|
"""
|
|
2126
2122
|
try:
|
|
2127
2123
|
self.service.request(
|
|
@@ -2249,12 +2245,9 @@ class ILAdminQmgr:
|
|
|
2249
2245
|
Note:
|
|
2250
2246
|
큐 관리자 전체(:meth:`setSystemTrace`)보다 로그 부담이 훨씬 적다.
|
|
2251
2247
|
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
뒤집혀 있다** - 성공하면 빈 사유로 예외가 나고, 실패하면 조용히 통과한다.
|
|
2256
|
-
파이썬은 ``MIMQ_SUCCESSFUL_*`` 로 바로잡았다(실서버 확인: 성공 4208 /
|
|
2257
|
-
실패 4209). **Java 쪽도 고쳐야 한다.**
|
|
2248
|
+
Note:
|
|
2249
|
+
성공 판정은 ``MIMQ_SUCCESSFUL_*`` 응답으로 한다(실서버 확인: 성공 4208 /
|
|
2250
|
+
실패 4209).
|
|
2258
2251
|
"""
|
|
2259
2252
|
try:
|
|
2260
2253
|
self.service.request(
|
|
@@ -2940,12 +2933,9 @@ class ILAdminQmgr:
|
|
|
2940
2933
|
p.setTraceEnabled(True)
|
|
2941
2934
|
qmgr.setQueueProperty(p)
|
|
2942
2935
|
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
뒤집혀 있다** - 성공하면 빈 사유로 예외가 나고, 실패하면 조용히 통과한다.
|
|
2947
|
-
파이썬은 ``MIMQ_SUCCESSFUL_*`` 로 바로잡았다(실서버 확인: 성공 4208 /
|
|
2948
|
-
실패 4209). **Java 쪽도 고쳐야 한다.**
|
|
2936
|
+
Note:
|
|
2937
|
+
성공 판정은 ``MIMQ_SUCCESSFUL_*`` 응답으로 한다(실서버 확인: 성공 4208 /
|
|
2938
|
+
실패 4209).
|
|
2949
2939
|
"""
|
|
2950
2940
|
try:
|
|
2951
2941
|
self.service.request(
|
|
@@ -3803,12 +3793,9 @@ class ILAdminQmgr:
|
|
|
3803
3793
|
Note:
|
|
3804
3794
|
채널이 붙지 않거나 자꾸 끊길 때 원인을 보는 데 쓴다.
|
|
3805
3795
|
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
뒤집혀 있다** - 성공하면 빈 사유로 예외가 나고, 실패하면 조용히 통과한다.
|
|
3810
|
-
파이썬은 ``MIMQ_SUCCESSFUL_*`` 로 바로잡았다(실서버 확인: 성공 4208 /
|
|
3811
|
-
실패 4209). **Java 쪽도 고쳐야 한다.**
|
|
3796
|
+
Note:
|
|
3797
|
+
성공 판정은 ``MIMQ_SUCCESSFUL_*`` 응답으로 한다(실서버 확인: 성공 4208 /
|
|
3798
|
+
실패 4209).
|
|
3812
3799
|
"""
|
|
3813
3800
|
try:
|
|
3814
3801
|
self.service.request(
|
|
@@ -3836,12 +3823,9 @@ class ILAdminQmgr:
|
|
|
3836
3823
|
ILOperationException: 그런 채널이 없거나 서버가 거절했을 때.
|
|
3837
3824
|
ILException: 통신 실패.
|
|
3838
3825
|
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
뒤집혀 있다** - 성공하면 빈 사유로 예외가 나고, 실패하면 조용히 통과한다.
|
|
3843
|
-
파이썬은 ``MIMQ_SUCCESSFUL_*`` 로 바로잡았다(실서버 확인: 성공 4208 /
|
|
3844
|
-
실패 4209). **Java 쪽도 고쳐야 한다.**
|
|
3826
|
+
Note:
|
|
3827
|
+
성공 판정은 ``MIMQ_SUCCESSFUL_*`` 응답으로 한다(실서버 확인: 성공 4208 /
|
|
3828
|
+
실패 4209).
|
|
3845
3829
|
"""
|
|
3846
3830
|
try:
|
|
3847
3831
|
self.service.request(
|
|
@@ -4261,9 +4245,7 @@ class ILAdminQmgr:
|
|
|
4261
4245
|
**토픽을 보려면 반드시 ``objectType`` 을 지정하라.**
|
|
4262
4246
|
|
|
4263
4247
|
Note:
|
|
4264
|
-
|
|
4265
|
-
여기서는 기존 호출부(``createObjectLogBrowser("TEST.LQ")``)를 깨지 않으려고
|
|
4266
|
-
**이름을 먼저** 받는다.
|
|
4248
|
+
인자 순서는 **이름이 먼저**다 - ``createObjectLogBrowser("TEST.LQ")``.
|
|
4267
4249
|
|
|
4268
4250
|
Example::
|
|
4269
4251
|
|
|
@@ -5057,6 +5039,151 @@ class ILAdminQmgr:
|
|
|
5057
5039
|
except Exception as exc:
|
|
5058
5040
|
raise ILException(exc) from exc
|
|
5059
5041
|
|
|
5042
|
+
# ── 관리 연결 pub/sub (엔진 rev 3295+) ─────────────────────────────
|
|
5043
|
+
def _relayTopic(self, code: int, ext, *args):
|
|
5044
|
+
"""토픽 요청을 큐 관리자로 릴레이한다(내부용).
|
|
5045
|
+
|
|
5046
|
+
관리 연결은 요청에 **대상 큐 관리자 이름**을 실어야 ilsvc 가 릴레이한다.
|
|
5047
|
+
"""
|
|
5048
|
+
return self.service.inquire_data_or_report(self.qmgrName, code, ext, *args)
|
|
5049
|
+
|
|
5050
|
+
def get_qmgr_name(self) -> str:
|
|
5051
|
+
"""이 핸들이 다루는 큐 관리자 이름.
|
|
5052
|
+
|
|
5053
|
+
Returns:
|
|
5054
|
+
str: 큐 관리자 이름.
|
|
5055
|
+
"""
|
|
5056
|
+
return self.qmgrName
|
|
5057
|
+
|
|
5058
|
+
def list_topic_names(self) -> list[str]:
|
|
5059
|
+
"""토픽 이름만 뽑아 목록으로 돌려준다.
|
|
5060
|
+
|
|
5061
|
+
Returns:
|
|
5062
|
+
list[str]: 토픽 이름 목록. 없으면 빈 목록.
|
|
5063
|
+
|
|
5064
|
+
Raises:
|
|
5065
|
+
ILOperationException: 서버가 조회를 거절했을 때.
|
|
5066
|
+
ILException: 통신 실패.
|
|
5067
|
+
|
|
5068
|
+
Note:
|
|
5069
|
+
:meth:`getTopicList` 가 돌려주는 ``|`` 구분 원문에서 첫 필드만 모은 것이다.
|
|
5070
|
+
오프셋이나 파티션 수까지 필요하면 :meth:`getTopicList` 를 쓰라.
|
|
5071
|
+
"""
|
|
5072
|
+
raw = self.getTopicList() or ""
|
|
5073
|
+
return [ln.split("|", 1)[0] for ln in raw.split("\n") if ln.strip()]
|
|
5074
|
+
|
|
5075
|
+
def accessTopic(self, topicName: str, existCheck: bool = True) -> "ILAdminTopic":
|
|
5076
|
+
"""**관리 연결로** 다룰 토픽 핸들을 얻는다.
|
|
5077
|
+
|
|
5078
|
+
큐 관리자 리스너 포트에 따로 붙지 않고 관리 포트 연결을 그대로 쓴다.
|
|
5079
|
+
방화벽이 관리 포트만 열린 환경에서 발행/구독을 할 때 쓴다.
|
|
5080
|
+
|
|
5081
|
+
Args:
|
|
5082
|
+
topicName (str): 토픽 이름.
|
|
5083
|
+
existCheck (bool): True(기본)면 토픽이 있는지 먼저 확인한다.
|
|
5084
|
+
|
|
5085
|
+
Returns:
|
|
5086
|
+
ILAdminTopic: 발행과 구독을 함께 하는 토픽 핸들.
|
|
5087
|
+
|
|
5088
|
+
Raises:
|
|
5089
|
+
ILOperationException: ``existCheck=True`` 인데 토픽이 없을 때.
|
|
5090
|
+
ILException: 통신 실패.
|
|
5091
|
+
|
|
5092
|
+
Warning:
|
|
5093
|
+
관리 연결에는 **배치가 없다.** 레코드 한 건에 한 번 왕복하므로 대량
|
|
5094
|
+
소비/발행에는 맞지 않는다. 처리량이 필요하면 리스너 포트에
|
|
5095
|
+
:class:`~ilink.qmgr.ILQmgr` 로 붙으라.
|
|
5096
|
+
|
|
5097
|
+
Note:
|
|
5098
|
+
엔진 **rev 3295 이상**이 필요하다.
|
|
5099
|
+
|
|
5100
|
+
Example::
|
|
5101
|
+
|
|
5102
|
+
aq = svc.accessAdminQmgr("QM1")
|
|
5103
|
+
topic = aq.accessTopic("ORDER.EVENT")
|
|
5104
|
+
|
|
5105
|
+
off, ts, part = topic.publish(b"payload", key="k1")
|
|
5106
|
+
|
|
5107
|
+
sub = topic.subscribe("audit")
|
|
5108
|
+
try:
|
|
5109
|
+
msg = sub.read(3000)
|
|
5110
|
+
print(msg.get_offset(), msg.get_data_string())
|
|
5111
|
+
sub.commit(msg)
|
|
5112
|
+
finally:
|
|
5113
|
+
sub.close()
|
|
5114
|
+
"""
|
|
5115
|
+
from .admintopic import ILAdminTopic
|
|
5116
|
+
return ILAdminTopic(self, topicName, existCheck)
|
|
5117
|
+
|
|
5118
|
+
def accessPattern(self, pattern: str):
|
|
5119
|
+
"""**관리 연결로** 다룰 토픽 패턴 핸들을 얻는다.
|
|
5120
|
+
|
|
5121
|
+
Args:
|
|
5122
|
+
pattern (str): 글롭 패턴(예 ``"ORDER.*"``). ``*`` 는 0자 이상으로
|
|
5123
|
+
구분자 ``.`` 도 삼키고, ``?`` 는 1자다. 비우면 거부한다.
|
|
5124
|
+
|
|
5125
|
+
Returns:
|
|
5126
|
+
ILTopicPattern: 패턴 핸들. **이 시점에는 서버와 통신하지 않는다.**
|
|
5127
|
+
|
|
5128
|
+
Raises:
|
|
5129
|
+
ILOperationException: 패턴이 비었을 때.
|
|
5130
|
+
|
|
5131
|
+
Warning:
|
|
5132
|
+
관리 연결에는 배치 read 가 없어, 패턴 구독도 하위 토픽을 **한 건씩**
|
|
5133
|
+
훑는다. 매칭 토픽이 많으면 왕복 수가 그만큼 늘어난다.
|
|
5134
|
+
|
|
5135
|
+
Example::
|
|
5136
|
+
|
|
5137
|
+
pat = aq.accessPattern("ORDER.*")
|
|
5138
|
+
print(pat.resolve()) # 구독 전 오타 확인
|
|
5139
|
+
|
|
5140
|
+
ps = pat.subscribe("audit")
|
|
5141
|
+
try:
|
|
5142
|
+
for msg in ps.read_batch(10, 3000):
|
|
5143
|
+
print(msg.get_topic_name(), msg.get_offset())
|
|
5144
|
+
ps.commit_sync()
|
|
5145
|
+
finally:
|
|
5146
|
+
ps.close()
|
|
5147
|
+
"""
|
|
5148
|
+
from .pattern import ILTopicPattern
|
|
5149
|
+
return ILTopicPattern(self, pattern)
|
|
5150
|
+
|
|
5151
|
+
def publish(self, topicName: str, value: bytes, key: str = "",
|
|
5152
|
+
partition: int | None = None) -> tuple[int, int, int]:
|
|
5153
|
+
"""관리 연결로 레코드 **한 건**을 발행한다.
|
|
5154
|
+
|
|
5155
|
+
:meth:`accessTopic` 없이 바로 한 건 보낼 때 쓰는 지름길이다.
|
|
5156
|
+
|
|
5157
|
+
Args:
|
|
5158
|
+
topicName (str): 대상 토픽 이름.
|
|
5159
|
+
value (bytes): payload. 빈 값도 허용한다(컴팩션 tombstone).
|
|
5160
|
+
key (str): 파티션 라우팅 키. **UTF-8 69바이트 이하.** 비우면 서버가 고른다.
|
|
5161
|
+
partition (int | None): 파티션 직접 지정. None(기본)이면 서버가 정한다.
|
|
5162
|
+
|
|
5163
|
+
Returns:
|
|
5164
|
+
tuple[int, int, int]: ``(offset, timestamp, partition)``.
|
|
5165
|
+
timestamp 는 epoch 밀리초.
|
|
5166
|
+
|
|
5167
|
+
Raises:
|
|
5168
|
+
ILOperationException: 토픽이 없거나 키가 69바이트를 넘거나 서버가 거절했을 때.
|
|
5169
|
+
ILException: 통신 실패.
|
|
5170
|
+
|
|
5171
|
+
Warning:
|
|
5172
|
+
**멱등 발행이 아니다.** 재시도하면 중복이 생길 수 있다.
|
|
5173
|
+
|
|
5174
|
+
Note:
|
|
5175
|
+
엔진 **rev 3295 이상**이 필요하다.
|
|
5176
|
+
|
|
5177
|
+
Example::
|
|
5178
|
+
|
|
5179
|
+
off, ts, part = aq.publish("ORDER.EVENT", b"payload", key="k1")
|
|
5180
|
+
"""
|
|
5181
|
+
return self.accessTopic(topicName, False).publish(value, key, partition)
|
|
5182
|
+
|
|
5183
|
+
access_topic = accessTopic
|
|
5184
|
+
access_pattern = accessPattern
|
|
5185
|
+
getQmgrName = get_qmgr_name
|
|
5186
|
+
|
|
5060
5187
|
# snake_case 별칭 (이 패키지 관례 - 두 표기를 모두 제공한다)
|
|
5061
5188
|
def create_topic(self, topic_name: str, options: str = "") -> None:
|
|
5062
5189
|
""":meth:`createTopic` 의 snake 별칭."""
|