jetstream-api 0.14.0__tar.gz → 0.16.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.
Files changed (27) hide show
  1. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/PKG-INFO +62 -1
  2. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/README.md +61 -0
  3. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/__init__.py +3 -1
  4. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/admin.py +7 -7
  5. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/common.py +4 -1
  6. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/properties.py +210 -36
  7. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/PKG-INFO +62 -1
  8. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/pyproject.toml +1 -1
  9. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/LICENSE.txt +0 -0
  10. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/_codec.py +0 -0
  11. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/admintopic.py +0 -0
  12. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/connectivity.py +0 -0
  13. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/exception.py +0 -0
  14. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/msg.py +0 -0
  15. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/partitioner.py +0 -0
  16. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/pattern.py +0 -0
  17. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/producer.py +0 -0
  18. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/py.typed +0 -0
  19. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/qmgr.py +0 -0
  20. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/topic.py +0 -0
  21. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/util.py +0 -0
  22. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/SOURCES.txt +0 -0
  23. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/dependency_links.txt +0 -0
  24. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/requires.txt +0 -0
  25. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/top_level.txt +0 -0
  26. {jetstream_api-0.14.0 → jetstream_api-0.16.0}/setup.cfg +0 -0
  27. {jetstream_api-0.14.0 → jetstream_api-0.16.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.14.0
3
+ Version: 0.16.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
@@ -60,6 +60,67 @@ lz4 배치 압축을 쓰려면 `pip install "jetstream-api[lz4]"`, zstd 배치
60
60
  ## 설치 방법
61
61
  pip install jetstream-api
62
62
 
63
+ ## 0.16.0 변경 - 세그먼트 이름을 토픽과 같은 형식으로, 오타 대입 거부 (자바 v2.12.0 과 같음)
64
+
65
+ - **이름 규칙이 정해졌습니다 - 개수는 맨 복수형, 목록은 `...List` 접미.** 토픽이 `partitions` 를 쓰는 형식 그대로입니다.
66
+ 0.15.0 이 하루 쓴 이름 둘을 여기로 옮깁니다.
67
+
68
+ | 자리 | 0.15.0 | **0.16.0** |
69
+ |---|---|---|
70
+ | 세그먼트 **개수** (`ILQueueProperty`) | `numberOfSegment` | **`segments`** |
71
+ | 세그먼트 **목록** (`ILQueueRealTimeInfo`) | `segments` | **`segmentInfoList`** |
72
+
73
+ - ★ **0.15.0 의 두 이름은 남기지 않고 지웠습니다.** 남기면 개수에 이름이 셋이 되고, 더 나쁘게는 `segments` 가
74
+ 클래스마다 다른 뜻(개수 vs 목록)이 됩니다. 0.15.0 은 하루짜리였고, 아래 가드 덕분에 **지운 것이 조용하지 않습니다.**
75
+ - **`numberOfPartition` 과 `partitions` 는 그대로 있습니다.** 예전부터 쓰던 이름이라 영구 별칭으로 남습니다.
76
+ - 큐에 진짜 분산 파티션이 생기면 그 수는 **토픽과 같은 이름(`partitions`)** 으로 따로 들어옵니다. 지금 있는 이름을
77
+ 그쪽으로 돌리지 않습니다 - **재사용은 제거보다 나쁩니다.** 제거는 그 자리에서 터지지만 재사용은 조용히 다른 값을 줍니다.
78
+ - **속성 객체가 모르는 필드 이름 대입을 거부합니다.** 지금까지는 `prop.numberOfSegmnet = 4` 같은 오타가 **예외도 없이**
79
+ 쓰레기 속성을 만들고 실제 값은 그대로였습니다 - 읽기는 원래 `AttributeError` 였는데 **쓰기만 침묵**해서 옛 값이 그대로
80
+ 서버로 나갔습니다.
81
+ - 이름이 바뀐 필드는 **무엇으로 바뀌었는지까지** 알려 줍니다:
82
+ `AttributeError: ILQueueProperty has no attribute numberOfSegment - 0.16.0 에서 segments 로 바뀌었다`
83
+ - 정말 임의 속성을 얹어야 하면 `object.__setattr__(obj, name, value)` 로 우회할 수 있습니다. 그 값은 **와이어에 실리지
84
+ 않습니다.**
85
+ - 생성자가 도는 동안은 열려 있습니다(필드를 만들어야 하므로). 상속해 쓰는 응용도 `super().__init__()` 뒤에 자기 필드를
86
+ 만들 수 있습니다.
87
+ - **와이어는 달라지지 않습니다.** 0.15.0 과 바이트가 같습니다(큐 속성 2200 · 구엔진 4096 · 실시간정보). 이 판도 엔진 판을 가리지 않습니다.
88
+
89
+ ## 0.15.0 변경 - 큐의 "파티션" 이 "세그먼트" 가 됩니다 (자바 v2.11.0 과 같음)
90
+
91
+ - **`ILQueueProperty.numberOfPartition` 이 `numberOfSegment` 로 바뀝니다.** 값도 자리도 그대로이고 **이름만** 바뀝니다.
92
+ - **옛 이름은 그대로 돕니다.** `numberOfPartition` 은 같은 값을 가리키는 별칭으로 남습니다 - 읽기도 쓰기도 되고,
93
+ `getNumberOfPartition()` / `setNumberOfPartition()` 도 전처럼 동작합니다. **고치지 않아도 되는 변경입니다.**
94
+ - `__str__` 라벨이 `NUM-PARTITION` 에서 `NUM-SEGMENT` 로 바뀝니다. 이 출력을 정규식으로 읽는 곳이 있으면 그곳만 봐 주세요.
95
+ - **왜 바꾸는지**: 같은 "파티션" 이라는 말이 토픽과 큐에서 **정반대** 를 뜻하고 있었습니다.
96
+
97
+ | 말 | 뜻 |
98
+ |---|---|
99
+ | 파티션 | **분산 처리 단위** (토픽. 리더 · 팔로워가 붙는다) |
100
+ | 세그먼트 | **한 노드 안의 저장 칸** (큐. 파일 1~N, 메모리, 공유메모리) |
101
+
102
+ 토픽의 `PARTITIONS` 와 큐의 `PARTITION` 이 한 글자 차이로 서로 다른 개념이었습니다. 엔진이 큐에 진짜 분산 파티션을
103
+ 들이기 전에 옛 이름을 비워 두는 것입니다.
104
+ - **와이어는 달라지지 않습니다.** 큐 속성 직렬화는 위치 기반 고정폭이라 **속성 이름이 실리지 않습니다.** 어느 이름으로
105
+ 넣든 나가는 2200바이트(구엔진용 4096 레이아웃도)가 같습니다. 그래서 이 판은 **엔진 판을 가리지 않습니다.**
106
+ - **엔진 쪽 이름도 같이 바뀝니다**(ilsc `PARTITION(n)` -> `SEGMENT(n)`, `VIEW QUEUE` 머리글, 컨피그 XML
107
+ `Storage/@NumberOfPartition` -> `@NumberOfSegment`). 엔진도 옛 이름을 계속 받습니다.
108
+ - ★ **ilsc 에서 `SEGMENT` 를 쓰려면 엔진도 같이 올려야 합니다.** 클라이언트만 올린 환경에서는 엔진이 그 키워드를
109
+ 모릅니다 - 그때도 큐는 정상 동작하고, ilsc 에서 `PARTITION` 을 쓰면 됩니다.
110
+ - **큐 실시간 정보의 "파티션" 목록도 같이 바뀝니다.** `getQueueRealTimeInfo()` 가 돌려주는
111
+ `ILQueueRealTimeInfo` 의 `partitions` 가 **`segments`** 가 되고, 항목 클래스 `PartitionItem` 은 **`SegmentItem`** 이 됩니다.
112
+ - 여기도 **옛 이름이 그대로 돕니다.** `partitions` 는 같은 목록을 가리키는 별칭이고(`getPartitions()` / `setPartitions()` 포함),
113
+ `PartitionItem` 은 `SegmentItem` 과 **같은 클래스 객체**라 `isinstance` 도 전처럼 통합니다.
114
+ - ★ **토픽의 `getPartitions()` 와는 뜻이 다릅니다.** 지금까지 두 클래스에서 **같은 이름이 정반대**를 뜻하고 있었습니다 -
115
+ 토픽 쪽은 분산 처리 단위, 큐 실시간 정보 쪽은 한 노드 안의 저장 칸입니다. 이번 개명의 목적이 바로 이것입니다.
116
+ - `__str__` 머리글이 `Partitions ---` 에서 `Segments ---` 로 바뀝니다(엔진 `VIEW QUEUE` 가 `SEGMENTS(` 로 나가는 것과 맞춥니다).
117
+ - `ILC.MIMQ_VO_SEGMENT_ITEM_LEN` 이 생기고 `ILC.MIMQ_VO_PARTITION_ITEM_LEN` 은 같은 값(128)의 별칭으로 남습니다.
118
+ - **자바 클라이언트는 클래스 이름을 바꾸지 않습니다**(`PartitionItem` 유지, `getSegments()` 추가). 자바는 제네릭이 불변이라
119
+ `ArrayList<PartitionItem>` 을 별칭으로 덮을 수 없고, 사본으로 옛 접근자를 만들면 목록 수정이 조용히 사라지기 때문입니다.
120
+ 파이썬은 클래스 별칭이 완전해서 이런 제약이 없습니다.
121
+ - **없어진 이름은 하나도 없습니다.** 이 판은 **추가와 별칭뿐**입니다.
122
+ - **디스크 파일 이름은 그대로입니다** (`QUEUE.P001`). 저장 레이아웃 자체라 바꾸지 않습니다.
123
+
63
124
  ## 0.14.0 변경 - 소켓 keepalive 탐침 타이머, NIO 커넥터 수신 기한 정합 (자바 v2.10.0 과 같음)
64
125
 
65
126
  - **연결 소켓에 keepalive 탐침 타이머를 겁니다(유휴 60초 + 10초 간격 x 6회).** 엔진이 쓰는 값과 같습니다.
@@ -10,6 +10,67 @@ lz4 배치 압축을 쓰려면 `pip install "jetstream-api[lz4]"`, zstd 배치
10
10
  ## 설치 방법
11
11
  pip install jetstream-api
12
12
 
13
+ ## 0.16.0 변경 - 세그먼트 이름을 토픽과 같은 형식으로, 오타 대입 거부 (자바 v2.12.0 과 같음)
14
+
15
+ - **이름 규칙이 정해졌습니다 - 개수는 맨 복수형, 목록은 `...List` 접미.** 토픽이 `partitions` 를 쓰는 형식 그대로입니다.
16
+ 0.15.0 이 하루 쓴 이름 둘을 여기로 옮깁니다.
17
+
18
+ | 자리 | 0.15.0 | **0.16.0** |
19
+ |---|---|---|
20
+ | 세그먼트 **개수** (`ILQueueProperty`) | `numberOfSegment` | **`segments`** |
21
+ | 세그먼트 **목록** (`ILQueueRealTimeInfo`) | `segments` | **`segmentInfoList`** |
22
+
23
+ - ★ **0.15.0 의 두 이름은 남기지 않고 지웠습니다.** 남기면 개수에 이름이 셋이 되고, 더 나쁘게는 `segments` 가
24
+ 클래스마다 다른 뜻(개수 vs 목록)이 됩니다. 0.15.0 은 하루짜리였고, 아래 가드 덕분에 **지운 것이 조용하지 않습니다.**
25
+ - **`numberOfPartition` 과 `partitions` 는 그대로 있습니다.** 예전부터 쓰던 이름이라 영구 별칭으로 남습니다.
26
+ - 큐에 진짜 분산 파티션이 생기면 그 수는 **토픽과 같은 이름(`partitions`)** 으로 따로 들어옵니다. 지금 있는 이름을
27
+ 그쪽으로 돌리지 않습니다 - **재사용은 제거보다 나쁩니다.** 제거는 그 자리에서 터지지만 재사용은 조용히 다른 값을 줍니다.
28
+ - **속성 객체가 모르는 필드 이름 대입을 거부합니다.** 지금까지는 `prop.numberOfSegmnet = 4` 같은 오타가 **예외도 없이**
29
+ 쓰레기 속성을 만들고 실제 값은 그대로였습니다 - 읽기는 원래 `AttributeError` 였는데 **쓰기만 침묵**해서 옛 값이 그대로
30
+ 서버로 나갔습니다.
31
+ - 이름이 바뀐 필드는 **무엇으로 바뀌었는지까지** 알려 줍니다:
32
+ `AttributeError: ILQueueProperty has no attribute numberOfSegment - 0.16.0 에서 segments 로 바뀌었다`
33
+ - 정말 임의 속성을 얹어야 하면 `object.__setattr__(obj, name, value)` 로 우회할 수 있습니다. 그 값은 **와이어에 실리지
34
+ 않습니다.**
35
+ - 생성자가 도는 동안은 열려 있습니다(필드를 만들어야 하므로). 상속해 쓰는 응용도 `super().__init__()` 뒤에 자기 필드를
36
+ 만들 수 있습니다.
37
+ - **와이어는 달라지지 않습니다.** 0.15.0 과 바이트가 같습니다(큐 속성 2200 · 구엔진 4096 · 실시간정보). 이 판도 엔진 판을 가리지 않습니다.
38
+
39
+ ## 0.15.0 변경 - 큐의 "파티션" 이 "세그먼트" 가 됩니다 (자바 v2.11.0 과 같음)
40
+
41
+ - **`ILQueueProperty.numberOfPartition` 이 `numberOfSegment` 로 바뀝니다.** 값도 자리도 그대로이고 **이름만** 바뀝니다.
42
+ - **옛 이름은 그대로 돕니다.** `numberOfPartition` 은 같은 값을 가리키는 별칭으로 남습니다 - 읽기도 쓰기도 되고,
43
+ `getNumberOfPartition()` / `setNumberOfPartition()` 도 전처럼 동작합니다. **고치지 않아도 되는 변경입니다.**
44
+ - `__str__` 라벨이 `NUM-PARTITION` 에서 `NUM-SEGMENT` 로 바뀝니다. 이 출력을 정규식으로 읽는 곳이 있으면 그곳만 봐 주세요.
45
+ - **왜 바꾸는지**: 같은 "파티션" 이라는 말이 토픽과 큐에서 **정반대** 를 뜻하고 있었습니다.
46
+
47
+ | 말 | 뜻 |
48
+ |---|---|
49
+ | 파티션 | **분산 처리 단위** (토픽. 리더 · 팔로워가 붙는다) |
50
+ | 세그먼트 | **한 노드 안의 저장 칸** (큐. 파일 1~N, 메모리, 공유메모리) |
51
+
52
+ 토픽의 `PARTITIONS` 와 큐의 `PARTITION` 이 한 글자 차이로 서로 다른 개념이었습니다. 엔진이 큐에 진짜 분산 파티션을
53
+ 들이기 전에 옛 이름을 비워 두는 것입니다.
54
+ - **와이어는 달라지지 않습니다.** 큐 속성 직렬화는 위치 기반 고정폭이라 **속성 이름이 실리지 않습니다.** 어느 이름으로
55
+ 넣든 나가는 2200바이트(구엔진용 4096 레이아웃도)가 같습니다. 그래서 이 판은 **엔진 판을 가리지 않습니다.**
56
+ - **엔진 쪽 이름도 같이 바뀝니다**(ilsc `PARTITION(n)` -> `SEGMENT(n)`, `VIEW QUEUE` 머리글, 컨피그 XML
57
+ `Storage/@NumberOfPartition` -> `@NumberOfSegment`). 엔진도 옛 이름을 계속 받습니다.
58
+ - ★ **ilsc 에서 `SEGMENT` 를 쓰려면 엔진도 같이 올려야 합니다.** 클라이언트만 올린 환경에서는 엔진이 그 키워드를
59
+ 모릅니다 - 그때도 큐는 정상 동작하고, ilsc 에서 `PARTITION` 을 쓰면 됩니다.
60
+ - **큐 실시간 정보의 "파티션" 목록도 같이 바뀝니다.** `getQueueRealTimeInfo()` 가 돌려주는
61
+ `ILQueueRealTimeInfo` 의 `partitions` 가 **`segments`** 가 되고, 항목 클래스 `PartitionItem` 은 **`SegmentItem`** 이 됩니다.
62
+ - 여기도 **옛 이름이 그대로 돕니다.** `partitions` 는 같은 목록을 가리키는 별칭이고(`getPartitions()` / `setPartitions()` 포함),
63
+ `PartitionItem` 은 `SegmentItem` 과 **같은 클래스 객체**라 `isinstance` 도 전처럼 통합니다.
64
+ - ★ **토픽의 `getPartitions()` 와는 뜻이 다릅니다.** 지금까지 두 클래스에서 **같은 이름이 정반대**를 뜻하고 있었습니다 -
65
+ 토픽 쪽은 분산 처리 단위, 큐 실시간 정보 쪽은 한 노드 안의 저장 칸입니다. 이번 개명의 목적이 바로 이것입니다.
66
+ - `__str__` 머리글이 `Partitions ---` 에서 `Segments ---` 로 바뀝니다(엔진 `VIEW QUEUE` 가 `SEGMENTS(` 로 나가는 것과 맞춥니다).
67
+ - `ILC.MIMQ_VO_SEGMENT_ITEM_LEN` 이 생기고 `ILC.MIMQ_VO_PARTITION_ITEM_LEN` 은 같은 값(128)의 별칭으로 남습니다.
68
+ - **자바 클라이언트는 클래스 이름을 바꾸지 않습니다**(`PartitionItem` 유지, `getSegments()` 추가). 자바는 제네릭이 불변이라
69
+ `ArrayList<PartitionItem>` 을 별칭으로 덮을 수 없고, 사본으로 옛 접근자를 만들면 목록 수정이 조용히 사라지기 때문입니다.
70
+ 파이썬은 클래스 별칭이 완전해서 이런 제약이 없습니다.
71
+ - **없어진 이름은 하나도 없습니다.** 이 판은 **추가와 별칭뿐**입니다.
72
+ - **디스크 파일 이름은 그대로입니다** (`QUEUE.P001`). 저장 레이아웃 자체라 바꾸지 않습니다.
73
+
13
74
  ## 0.14.0 변경 - 소켓 keepalive 탐침 타이머, NIO 커넥터 수신 기한 정합 (자바 v2.10.0 과 같음)
14
75
 
15
76
  - **연결 소켓에 keepalive 탐침 타이머를 겁니다(유휴 60초 + 10초 간격 x 6회).** 엔진이 쓰는 값과 같습니다.
@@ -1,6 +1,6 @@
1
1
  """iLink - Python client API for iLink M.O.M. (Message Oriented Middleware)."""
2
2
 
3
- __version__ = "0.14.0"
3
+ __version__ = "0.16.0"
4
4
 
5
5
  # --- Admin / Service ---
6
6
  from .admin import ILAdminService, ILAdminQmgr, ILLogBrowser, ILQueueBrowser
@@ -18,6 +18,7 @@ from .common import ILC, ILCC, ILRC, MatchOption
18
18
  from .properties import (
19
19
  DestItem,
20
20
  PartitionItem,
21
+ SegmentItem,
21
22
  ILQueueProperty,
22
23
  ILChannelProperty,
23
24
  ILChannelType,
@@ -71,6 +72,7 @@ __all__ = [
71
72
  # Properties
72
73
  "DestItem",
73
74
  "PartitionItem",
75
+ "SegmentItem",
74
76
  "ILQueueProperty",
75
77
  "ILChannelProperty",
76
78
  "ILChannelType",
@@ -629,7 +629,7 @@ class ILAdminService:
629
629
 
630
630
  Note:
631
631
  **값 범위를 검사하는 항목은 넷뿐이다.** 나머지(큐 깊이, 메시지 길이,
632
- 만료, 파티션 수 등)는 무엇을 넣어도 그대로 저장되므로 **부르는 쪽이
632
+ 만료, 세그먼트 수 등)는 무엇을 넣어도 그대로 저장되므로 **부르는 쪽이
633
633
  지켜야 한다.** 서버가 막아 줄 것이라 기대하지 마라.
634
634
 
635
635
  ====================== ================ ========== ===================
@@ -3545,7 +3545,7 @@ class ILAdminQmgr:
3545
3545
  큐 속성은 엔진 6.3.3 에서 전송 레이아웃이 한 번 바뀐 **유일한**
3546
3546
  속성이다(4096 -> 2200). 붙어 있는 엔진의 리비전을 보고 알아서 옛
3547
3547
  레이아웃으로 보내므로 호출부는 달라질 게 없다. 다만 구엔진에는
3548
- 만료(``expiry``)/영속성(``deliveryMode``)/파티션 설정이 아예 없어
3548
+ 만료(``expiry``)/영속성(``deliveryMode``)/세그먼트 설정이 아예 없어
3549
3549
  **그 값들은 무시된다** - 설정해도 반영되지 않는다.
3550
3550
  """
3551
3551
  try:
@@ -3861,7 +3861,7 @@ class ILAdminQmgr:
3861
3861
  큐 속성은 엔진 6.3.3 에서 전송 레이아웃이 한 번 바뀐 **유일한**
3862
3862
  속성이다(4096 -> 2200). 붙어 있는 엔진의 리비전을 보고 알아서 옛
3863
3863
  레이아웃으로 보내므로 호출부는 달라질 게 없다. 다만 구엔진에는
3864
- 만료(``expiry``)/영속성(``deliveryMode``)/파티션 설정이 아예 없어
3864
+ 만료(``expiry``)/영속성(``deliveryMode``)/세그먼트 설정이 아예 없어
3865
3865
  **그 값들은 무시된다** - 설정해도 반영되지 않는다.
3866
3866
  """
3867
3867
  try:
@@ -5523,7 +5523,7 @@ class ILAdminQmgr:
5523
5523
  Returns:
5524
5524
  ILQueueRealTimeInfo: 현재 깊이, 미커밋 put/get 건수, 열려 있는
5525
5525
  클라이언트/채널 수, 마지막 put/get 을 한 클라이언트와 시각,
5526
- 파티션별 상세(``getPartitions()``).
5526
+ 세그먼트별 상세(``getSegmentInfoList()``).
5527
5527
 
5528
5528
  Raises:
5529
5529
  ILOperationException: 그런 큐가 없을 때.
@@ -5538,9 +5538,9 @@ class ILAdminQmgr:
5538
5538
  그 시절 엔진은 이 요청에 **큐 속성 블롭을 통째로** 답한다. 사용 현황
5539
5539
  통계가 속성 안에 들어 있었기 때문이다. 클라이언트가 알아서 판별해
5540
5540
  같은 필드를 채우므로 호출부는 달라질 게 없다. 다만
5541
- :attr:`~ilink.properties.ILQueueRealTimeInfo.partitions` 는 **빈
5542
- 목록**이다 - 파티셔닝은 6.3.3 에서 들어온 기능이라 구엔진 큐에는
5543
- 파티션이라는 개념 자체가 없다.
5541
+ :attr:`~ilink.properties.ILQueueRealTimeInfo.segmentInfoList` 는 **빈
5542
+ 목록**이다 - 저장 칸 나누기는 6.3.3 에서 들어온 기능이라 구엔진 큐에는
5543
+ 세그먼트라는 개념 자체가 없다.
5544
5544
  """
5545
5545
  try:
5546
5546
  res_msg = self.service.inquire(
@@ -858,7 +858,10 @@ class ILC:
858
858
  MIMQ_VO_CHANNEL_LEN = 2048
859
859
  MIMQ_VO_DEST_ITEM_LEN = 1024
860
860
  MIMQ_VO_QUEUE_INFO_LEN = 512
861
- MIMQ_VO_PARTITION_ITEM_LEN = 128
861
+ #: 세그먼트 적재 항목 하나의 고정폭(엔진 ``SEGMENT_INFO_C_LENGTH``).
862
+ MIMQ_VO_SEGMENT_ITEM_LEN = 128
863
+ #: ``MIMQ_VO_SEGMENT_ITEM_LEN`` 의 **옛 이름**. 엔진 7.x(SVN 3448) 개명 전 이름이다.
864
+ MIMQ_VO_PARTITION_ITEM_LEN = MIMQ_VO_SEGMENT_ITEM_LEN
862
865
  MIMQ_VO_ACCESSRULE_LEN = 94
863
866
  MIMQ_VO_CERTFILE_LEN = 512
864
867
  MIMQ_VO_SPOKEINFO_LEN = 128
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime
4
+ import functools
4
5
  from enum import IntEnum
5
6
  from typing import List
6
7
 
@@ -94,6 +95,75 @@ class _AutoAccessor:
94
95
  **세터를 쓴다.**
95
96
  """
96
97
 
98
+ #: 이 인스턴스의 필드 생성이 끝났는지. 생성자가 도는 동안은 False 다.
99
+ _il_sealed = False
100
+ #: 생성자 중첩 깊이. 하위 클래스가 ``super().__init__()`` 을 부를 때를 센다.
101
+ _il_init_depth = 0
102
+ #: 이름이 바뀐 필드. ``{옛 이름: (새 이름, 바뀐 판)}``. 오타 거부 문구에 실어
103
+ #: **무엇으로 바뀌었는지**까지 알려 준다 - 거부만 하면 부르는 쪽이 헤맨다.
104
+ _RENAMED: dict = {}
105
+
106
+ def __init_subclass__(cls, **kwargs) -> None:
107
+ """하위 클래스의 ``__init__`` 을 감싸 **끝나는 순간 봉인**한다.
108
+
109
+ Note:
110
+ 봉인 뒤에는 :meth:`__setattr__` 이 모르는 이름을 거부한다. 생성자가
111
+ 도는 동안은 필드를 만들어야 하므로 열어 둔다. ``super().__init__()``
112
+ 을 부르는 하위 클래스가 있으므로 **깊이를 세어 제일 바깥 생성자가
113
+ 끝날 때** 봉인한다 - 안쪽에서 봉인하면 하위 클래스가 자기 필드를
114
+ 만들지 못한다.
115
+ """
116
+ super().__init_subclass__(**kwargs)
117
+ init = cls.__dict__.get("__init__")
118
+ if init is None:
119
+ return
120
+
121
+ @functools.wraps(init)
122
+ def _wrapped(self, *args, **kw):
123
+ object.__setattr__(self, "_il_init_depth", self._il_init_depth + 1)
124
+ try:
125
+ init(self, *args, **kw)
126
+ finally:
127
+ depth = self._il_init_depth - 1
128
+ object.__setattr__(self, "_il_init_depth", depth)
129
+ if depth == 0:
130
+ object.__setattr__(self, "_il_sealed", True)
131
+
132
+ cls.__init__ = _wrapped
133
+
134
+ def __setattr__(self, name: str, value) -> None:
135
+ """**모르는 필드 이름 대입을 거부한다.**
136
+
137
+ Args:
138
+ name (str): 필드 이름.
139
+ value: 넣을 값.
140
+
141
+ Raises:
142
+ AttributeError: 그런 필드가 없을 때.
143
+
144
+ Note:
145
+ 전에는 오타가 **조용했다** - ``prop.numberOfSegmnet = 4`` 가 예외도
146
+ 없이 쓰레기 속성을 만들고 실제 값은 그대로였다. 읽기는 원래
147
+ ``AttributeError`` 였는데 **쓰기만 침묵해서** 와이어에 옛 값이 나갔다.
148
+
149
+ 정말 임의 속성을 얹어야 하면 ``object.__setattr__(obj, name, value)``
150
+ 로 우회할 수 있다. 그때는 **와이어에 실리지 않는다**는 것을 부르는
151
+ 쪽이 안다는 뜻이다.
152
+ """
153
+ if not self._il_sealed or name in self.__dict__ or hasattr(type(self), name):
154
+ object.__setattr__(self, name, value)
155
+ return
156
+ moved = type(self)._RENAMED.get(name)
157
+ if moved is not None:
158
+ raise AttributeError(
159
+ f"{self.__class__.__name__} has no attribute {name}"
160
+ f" - {moved[1]} 에서 {moved[0]} 로 바뀌었다"
161
+ )
162
+ raise AttributeError(
163
+ f"{self.__class__.__name__} has no attribute {name}"
164
+ f" - 필드 이름을 확인하라 (임의 속성을 얹으려면 object.__setattr__ 을 쓴다)"
165
+ )
166
+
97
167
  def __getattr__(self, name: str):
98
168
  """없는 속성 접근을 필드 기반 접근자로 해석한다.
99
169
 
@@ -324,11 +394,17 @@ class DestItem(_AutoAccessor):
324
394
  return ILC.MIMQ_ERROR_STR
325
395
 
326
396
 
327
- class PartitionItem(_AutoAccessor):
328
- """큐 파티션 하나의 적재 현황. :class:`ILQueueRealTimeInfo` 안에 목록으로 들어간다.
397
+ class SegmentItem(_AutoAccessor):
398
+ """큐 **세그먼트**(저장 칸) 하나의 적재 현황. :class:`ILQueueRealTimeInfo` 안에
399
+ 목록으로 들어간다.
400
+
401
+ 세그먼트는 한 큐의 메시지를 나눠 담는 저장 칸이다(파일 1~N, 메모리, 공유메모리).
402
+ **토픽의 파티션과 달리 분산 처리 단위가 아니다.** 엔진 7.x(SVN 3448)에서 이름이
403
+ 갈리기 전에는 이 클래스가 ``PartitionItem`` 이었다 - 그 이름은 **별칭으로 남아
404
+ 있다**(``PartitionItem is SegmentItem`` 이라 ``isinstance`` 도 그대로 통한다).
329
405
 
330
406
  Attributes:
331
- size (int): 이 파티션이 쓰는 총 바이트. 기본 0.
407
+ size (int): 이 세그먼트가 쓰는 총 바이트. 기본 0.
332
408
  스펙: 기본 0 · 범위 0 이상 · 단위 byte · 변경 불가(ReadOnly).
333
409
  msgCnt (int): 적재된 메시지 수(확정분). 기본 0.
334
410
  스펙: 기본 0 · 범위 0 이상 · 단위 건 · 변경 불가(ReadOnly).
@@ -341,7 +417,7 @@ class PartitionItem(_AutoAccessor):
341
417
  """
342
418
 
343
419
  def __init__(self, ba: bytes | bytearray | None = None) -> None:
344
- """파티션 항목을 만든다.
420
+ """세그먼트 항목을 만든다.
345
421
 
346
422
  Args:
347
423
  ba (bytes | bytearray | None): 서버가 보낸 고정폭 바이트. None(기본)이면
@@ -361,10 +437,10 @@ class PartitionItem(_AutoAccessor):
361
437
  return
362
438
 
363
439
  try:
364
- if len(ba) < ILC.MIMQ_VO_PARTITION_ITEM_LEN:
440
+ if len(ba) < ILC.MIMQ_VO_SEGMENT_ITEM_LEN:
365
441
  raise ILDeserializeException(
366
442
  "invalid byte array length. fixed : ["
367
- + str(ILC.MIMQ_VO_PARTITION_ITEM_LEN)
443
+ + str(ILC.MIMQ_VO_SEGMENT_ITEM_LEN)
368
444
  + "] / actual : ["
369
445
  + str(len(ba))
370
446
  + "]"
@@ -393,7 +469,7 @@ class PartitionItem(_AutoAccessor):
393
469
  라이브러리가 요청을 보낼 때 내부적으로 부른다. 응용이 직접 부를
394
470
  일은 거의 없다.
395
471
  """
396
- ba = bytearray(ILC.MIMQ_VO_PARTITION_ITEM_LEN)
472
+ ba = bytearray(ILC.MIMQ_VO_SEGMENT_ITEM_LEN)
397
473
  offset = 0
398
474
  ba_merge(self.size, ba, offset, 20)
399
475
  offset += 20
@@ -411,7 +487,7 @@ class PartitionItem(_AutoAccessor):
411
487
  """사람이 읽는 여러 줄 요약을 돌려준다(운영 화면 출력용).
412
488
 
413
489
  Returns:
414
- str: 파티션 항목 를 보기 좋게 정리한 문자열. **형식이 고정되어 있지
490
+ str: 세그먼트 항목 를 보기 좋게 정리한 문자열. **형식이 고정되어 있지
415
491
  않으므로 파싱해 쓰지 말 것.**
416
492
  """
417
493
  return (
@@ -420,6 +496,12 @@ class PartitionItem(_AutoAccessor):
420
496
  )
421
497
 
422
498
 
499
+ #: :class:`SegmentItem` 의 **옛 이름**. 같은 클래스 객체라 ``isinstance`` 도 통한다.
500
+ #: 엔진 7.x(SVN 3448)에서 큐의 "파티션" 이 "세그먼트" 로 바뀌기 전 이름이다.
501
+ #: **영구히 세그먼트를 가리킨다** - 다른 뜻으로 재사용하지 않는다.
502
+ PartitionItem = SegmentItem
503
+
504
+
423
505
  class ILQueueMinorProperty(_AutoAccessor):
424
506
  """큐 **요약** 정보. 목록 조회(``getQueueMinorList``)가 돌려주는 가벼운 형태.
425
507
 
@@ -638,12 +720,27 @@ class ILQueueProperty(_AutoAccessor):
638
720
  스펙: 기본 10485760 · 범위 0~9223372036854775807 · 단위 byte · 변경 가능/재기동 불필요.
639
721
  sharedMemorySize (int): 공유 메모리 크기. 기본 0.
640
722
  스펙: 기본 DISABLED (0) · 범위 0~9223372036854775807 · 단위 byte · 변경 불가.
641
- numberOfPartition (int): 파일 파티션 개수. 기본 2.
723
+ segments (int): **세그먼트**(저장 칸) 개수. 기본 2.
724
+ 한 큐의 메시지를 나눠 담는 저장 칸의 수다 - 파일 1~N, 메모리,
725
+ 공유메모리가 그 칸이다. **토픽의 파티션과 달리 분산 처리 단위가
726
+ 아니다.** 생성 시에만 지정하고 이후 바꿀 수 없다.
727
+ **개수라 맨 복수형**이다 - 목록은 ``...List`` 접미를 쓴다
728
+ (:attr:`ILQueueRealTimeInfo.segmentInfoList`). 토픽의 ``partitions``
729
+ 와 같은 형식이다.
642
730
  스펙: 기본 2 · 범위 2~99 · 단위 개 · 변경 불가.
731
+ numberOfPartition (int): ``segments`` 의 **옛 이름**. 읽기·쓰기
732
+ 모두 같은 값을 가리키므로 기존 코드는 그대로 돈다. 엔진 7.x(SVN 3448)
733
+ 에서 큐의 "파티션" 이 "세그먼트" 로 바뀌면서 이름이 갈렸다 - 큐의
734
+ 저장 칸과 토픽의 분산 단위가 한 글자 차이로 정반대를 뜻하던 것을
735
+ 없앴다. **새 코드는** ``segments`` **를 쓴다.**
736
+ **이 이름은 영구히 세그먼트 개수를 가리킨다** - 다른 뜻으로
737
+ 재사용하지 않는다. 큐에 진짜 분산 파티션이 생겨도 그 수는
738
+ **토픽과 같은 이름**(``partitions``)으로 따로 들어온다.
739
+ 스펙: 별칭 · 와이어에는 이름이 실리지 않는다(위치 기반 고정폭).
643
740
  legacyBlob (bool): 이 객체가 **구버전(4096) 블롭**에서 만들어졌는지.
644
741
  엔진 rev 3155 미만이 보낸 응답이면 True 다. 그 경우 ``expiry`` /
645
742
  ``expiredQueue`` / ``deliveryMode`` / ``maxMemorySize`` /
646
- ``sharedMemorySize`` / ``numberOfPartition`` 은 **서버가 준 값이 아니라
743
+ ``sharedMemorySize`` / ``segments`` 는 **서버가 준 값이 아니라
647
744
  기본값**이다 - 구엔진에는 그 설정이 없다.
648
745
  스펙: 서버 응답 길이로 라이브러리가 판단하는 내부 표시 · 앱이 건드리지 않는다.
649
746
  """
@@ -658,6 +755,38 @@ class ILQueueProperty(_AutoAccessor):
658
755
  "expiredQueue": _spec_maxlen(47),
659
756
  }
660
757
 
758
+ #: 0.15.0 이 잠깐 쓴 이름. 그 판에서만 살았고 0.16.0 에서 ``segments`` 가 됐다.
759
+ _RENAMED = {"numberOfSegment": ("segments", "0.16.0")}
760
+
761
+ @property
762
+ def numberOfPartition(self) -> int:
763
+ """``segments`` 의 **옛 이름**. 읽기·쓰기 모두 같은 값이다.
764
+
765
+ Returns:
766
+ int: ``segments`` 와 같은 값.
767
+
768
+ Note:
769
+ 클래스 레벨 ``property`` 라서 대입도 받는다
770
+ (``prop.numberOfPartition = 4``). :class:`_AutoAccessor` 가 이름을
771
+ 보고 만들어 주는 ``getNumberOfPartition()`` /
772
+ ``setNumberOfPartition()`` 도 이 별칭을 통과한다.
773
+
774
+ **와이어에는 이름이 실리지 않는다** - 큐 속성 직렬화는 위치 기반
775
+ 고정폭이라 이 개명은 이름 층만의 변경이고 엔진 판과 무관하다.
776
+
777
+ **이 별칭은 영구히 세그먼트 수를 가리킨다.** 뜻을 바꿔 재사용하지
778
+ 않는다 - 재사용은 제거보다 나쁘기 때문이다. 제거는 ``AttributeError``
779
+ 로 그 자리에서 터지지만, 재사용은 **옛 코드가 조용히 다른 수를
780
+ 읽는다.** 큐의 분산 파티션 수는 ``partitions``
781
+ 으로 들어온다 - 토픽과 같은 이름 ``partitions`` 다
782
+ (엔진 ilsc ``PARTITIONS(n)`` · 컨피그 XML ``Partitions``).
783
+ """
784
+ return self.segments
785
+
786
+ @numberOfPartition.setter
787
+ def numberOfPartition(self, value: int) -> None:
788
+ self.segments = value
789
+
661
790
  def __init__(
662
791
  self,
663
792
  name: str | bytes | bytearray | None = None,
@@ -692,7 +821,7 @@ class ILQueueProperty(_AutoAccessor):
692
821
  self.deliveryMode = ILC.MIMQ_DELIVERY_MODE_DEPENDS_ON_MSG
693
822
  self.maxMemorySize = 10485760
694
823
  self.sharedMemorySize = 0
695
- self.numberOfPartition = 2
824
+ self.segments = 2
696
825
  #: 구버전(4096) 블롭에서 만들어졌는지. 내부 판별용.
697
826
  self.legacyBlob = False
698
827
 
@@ -766,7 +895,7 @@ class ILQueueProperty(_AutoAccessor):
766
895
  offset += 20
767
896
  self.sharedMemorySize = ba_pick_long(ba, offset, 20)
768
897
  offset += 20
769
- self.numberOfPartition = ba_pick_int(ba, offset, 10)
898
+ self.segments = ba_pick_int(ba, offset, 10)
770
899
  offset += 10
771
900
  offset += 228
772
901
  # ---- 공통 접미 (2142) ----
@@ -793,7 +922,7 @@ class ILQueueProperty(_AutoAccessor):
793
922
  보고 :class:`ILAdminQmgr` 가 정한다.
794
923
 
795
924
  구버전 레이아웃에는 ``expiry`` / ``expiredQueue`` / ``deliveryMode`` /
796
- ``maxMemorySize`` / ``sharedMemorySize`` / ``numberOfPartition`` 자리가
925
+ ``maxMemorySize`` / ``sharedMemorySize`` / ``segments`` 자리가
797
926
  **없다.** 그 값들은 실리지 않고 버려진다 - 구엔진이 모르는 설정이다.
798
927
  """
799
928
  if legacy:
@@ -837,7 +966,7 @@ class ILQueueProperty(_AutoAccessor):
837
966
  offset += 20
838
967
  ba_merge(self.sharedMemorySize, ba, offset, 20)
839
968
  offset += 20
840
- ba_merge(self.numberOfPartition, ba, offset, 10)
969
+ ba_merge(self.segments, ba, offset, 10)
841
970
  offset += 10
842
971
  offset += 228
843
972
  ba_merge(self.incomingDelayDepth, ba, offset, 10)
@@ -977,8 +1106,8 @@ class ILQueueProperty(_AutoAccessor):
977
1106
  + "bytes) SHARED-MEMORY-SIZE("
978
1107
  + str(self.sharedMemorySize)
979
1108
  + "bytes)\n"
980
- + "\tNUM-PARTITION ("
981
- + str(self.numberOfPartition)
1109
+ + "\tNUM-SEGMENT ("
1110
+ + str(self.segments)
982
1111
  + ") DELAY(over "
983
1112
  + str(self.incomingDelayDepth)
984
1113
  + "depth, "
@@ -1972,6 +2101,14 @@ class ILQueueRealTimeInfo(_AutoAccessor):
1972
2101
  채우지 않는다(직렬화에서 그 180바이트를 건너뛴다). 그래서 구엔진에
1973
2102
  붙었을 때만 값이 온다.
1974
2103
 
2104
+ ★ **그 180바이트는 빈 자리가 아니다.** 오프셋 30~210 이고, 이 네 필드가
2105
+ 정확히 그 폭을 채운다(20+20+70+70). 엔진이 건너뛰는 구간과 같은 자리이니
2106
+ **예약 공간으로 보이지만 임자가 있다** - 이 클라는 지금도 그 자리를
2107
+ 파싱한다. 여기에 새 필드를 실으면 옛 클라는 0 이 아니라 **쓰레기를 값으로**
2108
+ 읽고(문자열 칸이라 예외도 안 난다), 그 값이 :meth:`__str__` 의 ``LASTPUT``
2109
+ 줄로 그대로 나간다. 재사용하려면 **수신자가 새 뜻을 안다고 말한 뒤**
2110
+ 여야 한다(엔진 능력 선언).
2111
+
1975
2112
  6.3.3+ 에서 "누가 마지막으로 이 큐를 건드렸는지" 를 보려면 세션 쪽을
1976
2113
  보라 - :meth:`ILAdminQmgr.getSessionList` 가 주는
1977
2114
  :class:`ILSessionProperty` 의 ``lastAccessObject`` 가 그 정보를 세션
@@ -2000,10 +2137,47 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2000
2137
  스펙: 기본 0 · 범위 0 이상 · 단위 건 · 변경 불가(ReadOnly).
2001
2138
  uncommittedGet (int): 아직 커밋되지 않은 get 건수. 기본 0.
2002
2139
  스펙: 기본 0 · 범위 0 이상 · 단위 건 · 변경 불가(ReadOnly).
2003
- partitions (list[PartitionItem]): 파티션별 상세. 기본 빈 목록.
2004
- 스펙: 기본 빈 목록 · 범위 파티션 수만큼 · 변경 불가(ReadOnly).
2140
+ segmentInfoList (list[SegmentItem]): **세그먼트별** 상세. 기본 빈 목록.
2141
+ 목록이라 ``...List`` 접미를 쓴다 - 개수를 뜻하는 맨 복수형
2142
+ (:attr:`ILQueueProperty.segments`)과 구별된다.
2143
+ 스펙: 기본 빈 목록 · 범위 세그먼트 수만큼 · 변경 불가(ReadOnly).
2144
+ partitions (list[SegmentItem]): ``segmentInfoList`` 의 **옛 이름**. 읽기·쓰기 모두
2145
+ 같은 목록을 가리킨다. 엔진 7.x(SVN 3448)에서 큐의 저장 칸이
2146
+ "세그먼트" 가 되면서 이름이 갈렸다 - 토픽의 ``getPartitions()`` 는
2147
+ **분산 단위**라 뜻이 다르다. **새 코드는** ``segmentInfoList`` **를 쓴다.**
2148
+ **이 이름은 영구히 세그먼트 목록을 가리킨다** - 다른 뜻으로
2149
+ 재사용하지 않는다.
2150
+ 스펙: 별칭 · 와이어에는 이름이 실리지 않는다.
2005
2151
  """
2006
2152
 
2153
+ #: 0.15.0 이 잠깐 쓴 이름. 그 판에서만 살았고 0.16.0 에서 ``segmentInfoList`` 가 됐다.
2154
+ #: 이 이름을 비워 둔 덕에 :attr:`ILQueueProperty.segments`(세그먼트 **개수**)와
2155
+ #: 겹치지 않는다 - 같은 이름이 클래스마다 다른 뜻이 되는 것을 막는다.
2156
+ _RENAMED = {"segments": ("segmentInfoList", "0.16.0")}
2157
+
2158
+ @property
2159
+ def partitions(self) -> "List[SegmentItem]":
2160
+ """``segmentInfoList`` 의 **옛 이름**. 같은 목록을 가리킨다.
2161
+
2162
+ Returns:
2163
+ list[SegmentItem]: ``segmentInfoList`` 와 같은 목록 객체.
2164
+
2165
+ Note:
2166
+ :class:`_AutoAccessor` 가 만들어 주는 ``getPartitions()`` /
2167
+ ``setPartitions()`` 도 이 별칭을 통과한다. **토픽의**
2168
+ ``ILTopic.getPartitions()`` **와 이름은 같지만 뜻이 다르다** -
2169
+ 저쪽은 분산 처리 단위고 이쪽은 한 노드 안의 저장 칸이다.
2170
+
2171
+ **이 별칭은 영구히 세그먼트 목록을 가리킨다.** 큐에 분산 파티션이
2172
+ 생겨도 이 이름을 그쪽으로 돌리지 않는다 - 그러면 옛 코드가 조용히
2173
+ 다른 것을 읽는다.
2174
+ """
2175
+ return self.segmentInfoList
2176
+
2177
+ @partitions.setter
2178
+ def partitions(self, value: "List[SegmentItem]") -> None:
2179
+ self.segmentInfoList = value
2180
+
2007
2181
  # [spec-check] 문자열 상한 = 와이어 폭 - 1 (엔진이 C 문자열로 읽는다)
2008
2182
  _SPEC = {
2009
2183
  "lastPutClient": _spec_maxlen(69),
@@ -2031,7 +2205,7 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2031
2205
  self.numberOfChannel = 0
2032
2206
  self.uncommittedPut = 0
2033
2207
  self.uncommittedGet = 0
2034
- self.partitions: List[PartitionItem] = []
2208
+ self.segmentInfoList: List[SegmentItem] = []
2035
2209
 
2036
2210
  if ba is None:
2037
2211
  return
@@ -2068,11 +2242,11 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2068
2242
  count = ba_pick_int(ba, offset, 5)
2069
2243
  offset += 5
2070
2244
  for _ in range(count):
2071
- item = PartitionItem(
2072
- ba_pick_bytes(ba, offset, ILC.MIMQ_VO_PARTITION_ITEM_LEN)
2245
+ item = SegmentItem(
2246
+ ba_pick_bytes(ba, offset, ILC.MIMQ_VO_SEGMENT_ITEM_LEN)
2073
2247
  )
2074
- self.partitions.append(item)
2075
- offset += ILC.MIMQ_VO_PARTITION_ITEM_LEN
2248
+ self.segmentInfoList.append(item)
2249
+ offset += ILC.MIMQ_VO_SEGMENT_ITEM_LEN
2076
2250
  except Exception as exc:
2077
2251
  raise ILException(exc) from exc
2078
2252
 
@@ -2087,8 +2261,8 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2087
2261
  일은 거의 없다.
2088
2262
  """
2089
2263
  buffer_length = ILC.MIMQ_VO_QUEUE_INFO_LEN + ILC.MIMQ_LIST_ITEM_COUNT_LENGTH
2090
- if self.partitions:
2091
- buffer_length += len(self.partitions) * ILC.MIMQ_VO_PARTITION_ITEM_LEN
2264
+ if self.segmentInfoList:
2265
+ buffer_length += len(self.segmentInfoList) * ILC.MIMQ_VO_SEGMENT_ITEM_LEN
2092
2266
  ba = bytearray(buffer_length)
2093
2267
  offset = 0
2094
2268
  ba_merge(self.curDepth, ba, offset, 10)
@@ -2111,11 +2285,11 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2111
2285
  offset += 10
2112
2286
  ba_merge(self.uncommittedGet, ba, offset, 10)
2113
2287
  offset += 10
2114
- ba_merge(len(self.partitions), ba, offset, 5)
2288
+ ba_merge(len(self.segmentInfoList), ba, offset, 5)
2115
2289
  offset += 5
2116
- for item in self.partitions:
2117
- ba_merge(item.get_serialized(), ba, offset, ILC.MIMQ_VO_PARTITION_ITEM_LEN)
2118
- offset += ILC.MIMQ_VO_PARTITION_ITEM_LEN
2290
+ for item in self.segmentInfoList:
2291
+ ba_merge(item.get_serialized(), ba, offset, ILC.MIMQ_VO_SEGMENT_ITEM_LEN)
2292
+ offset += ILC.MIMQ_VO_SEGMENT_ITEM_LEN
2119
2293
  return bytes(ba)
2120
2294
 
2121
2295
  def __str__(self) -> str:
@@ -2138,9 +2312,9 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2138
2312
  ret += f"LASTGET(By {self.lastGetClient}, {self.lastGetTime})\n"
2139
2313
  ret += f"ACCESS(Client {self.numberOfClient}, Channel {self.numberOfChannel})\n"
2140
2314
  ret += f"TRANSACTED(Put {self.uncommittedPut}, Get {self.uncommittedGet})\n"
2141
- ret += "Partitions -------------------------------------------------------\n"
2142
- for partition in self.partitions:
2143
- ret += " " + str(partition)
2315
+ ret += "Segments ---------------------------------------------------------\n"
2316
+ for segment in self.segmentInfoList:
2317
+ ret += " " + str(segment)
2144
2318
  return ret
2145
2319
 
2146
2320
  @classmethod
@@ -2159,9 +2333,9 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2159
2333
  (6.3.3 에서 별도 조회로 분리됐다). 그래서 같은 응답으로 속성 객체와
2160
2334
  이 객체를 모두 채울 수 있다.
2161
2335
 
2162
- :attr:`partitions` 는 **빈 목록**이 된다. 파티셔닝은 6.3.3 에서 들어온
2163
- 기능이라 구엔진 큐에는 파티션이라는 개념 자체가 없다 - 누락이 아니라
2164
- 사실이다.
2336
+ :attr:`segmentInfoList` 는 **빈 목록**이 된다. 저장 칸 나누기는 6.3.3 에서
2337
+ 들어온 기능이라 구엔진 큐에는 세그먼트라는 개념 자체가 없다 - 누락이
2338
+ 아니라 사실이다.
2165
2339
  """
2166
2340
  o = ILC.QUEUE_LEGACY_DIVERGE_OFFSET
2167
2341
  info = cls()
@@ -2177,7 +2351,7 @@ class ILQueueRealTimeInfo(_AutoAccessor):
2177
2351
  # 현행 유량 조회(ILQueueFlow)는 **구간별** 값이라 의미가 달라 쓰지 않는다.
2178
2352
  info.uncommittedPut = ba_pick_int(ba, o + 300, 10)
2179
2353
  info.uncommittedGet = ba_pick_int(ba, o + 310, 10)
2180
- info.partitions = []
2354
+ info.segmentInfoList = []
2181
2355
  return info
2182
2356
 
2183
2357
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jetstream-api
3
- Version: 0.14.0
3
+ Version: 0.16.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
@@ -60,6 +60,67 @@ lz4 배치 압축을 쓰려면 `pip install "jetstream-api[lz4]"`, zstd 배치
60
60
  ## 설치 방법
61
61
  pip install jetstream-api
62
62
 
63
+ ## 0.16.0 변경 - 세그먼트 이름을 토픽과 같은 형식으로, 오타 대입 거부 (자바 v2.12.0 과 같음)
64
+
65
+ - **이름 규칙이 정해졌습니다 - 개수는 맨 복수형, 목록은 `...List` 접미.** 토픽이 `partitions` 를 쓰는 형식 그대로입니다.
66
+ 0.15.0 이 하루 쓴 이름 둘을 여기로 옮깁니다.
67
+
68
+ | 자리 | 0.15.0 | **0.16.0** |
69
+ |---|---|---|
70
+ | 세그먼트 **개수** (`ILQueueProperty`) | `numberOfSegment` | **`segments`** |
71
+ | 세그먼트 **목록** (`ILQueueRealTimeInfo`) | `segments` | **`segmentInfoList`** |
72
+
73
+ - ★ **0.15.0 의 두 이름은 남기지 않고 지웠습니다.** 남기면 개수에 이름이 셋이 되고, 더 나쁘게는 `segments` 가
74
+ 클래스마다 다른 뜻(개수 vs 목록)이 됩니다. 0.15.0 은 하루짜리였고, 아래 가드 덕분에 **지운 것이 조용하지 않습니다.**
75
+ - **`numberOfPartition` 과 `partitions` 는 그대로 있습니다.** 예전부터 쓰던 이름이라 영구 별칭으로 남습니다.
76
+ - 큐에 진짜 분산 파티션이 생기면 그 수는 **토픽과 같은 이름(`partitions`)** 으로 따로 들어옵니다. 지금 있는 이름을
77
+ 그쪽으로 돌리지 않습니다 - **재사용은 제거보다 나쁩니다.** 제거는 그 자리에서 터지지만 재사용은 조용히 다른 값을 줍니다.
78
+ - **속성 객체가 모르는 필드 이름 대입을 거부합니다.** 지금까지는 `prop.numberOfSegmnet = 4` 같은 오타가 **예외도 없이**
79
+ 쓰레기 속성을 만들고 실제 값은 그대로였습니다 - 읽기는 원래 `AttributeError` 였는데 **쓰기만 침묵**해서 옛 값이 그대로
80
+ 서버로 나갔습니다.
81
+ - 이름이 바뀐 필드는 **무엇으로 바뀌었는지까지** 알려 줍니다:
82
+ `AttributeError: ILQueueProperty has no attribute numberOfSegment - 0.16.0 에서 segments 로 바뀌었다`
83
+ - 정말 임의 속성을 얹어야 하면 `object.__setattr__(obj, name, value)` 로 우회할 수 있습니다. 그 값은 **와이어에 실리지
84
+ 않습니다.**
85
+ - 생성자가 도는 동안은 열려 있습니다(필드를 만들어야 하므로). 상속해 쓰는 응용도 `super().__init__()` 뒤에 자기 필드를
86
+ 만들 수 있습니다.
87
+ - **와이어는 달라지지 않습니다.** 0.15.0 과 바이트가 같습니다(큐 속성 2200 · 구엔진 4096 · 실시간정보). 이 판도 엔진 판을 가리지 않습니다.
88
+
89
+ ## 0.15.0 변경 - 큐의 "파티션" 이 "세그먼트" 가 됩니다 (자바 v2.11.0 과 같음)
90
+
91
+ - **`ILQueueProperty.numberOfPartition` 이 `numberOfSegment` 로 바뀝니다.** 값도 자리도 그대로이고 **이름만** 바뀝니다.
92
+ - **옛 이름은 그대로 돕니다.** `numberOfPartition` 은 같은 값을 가리키는 별칭으로 남습니다 - 읽기도 쓰기도 되고,
93
+ `getNumberOfPartition()` / `setNumberOfPartition()` 도 전처럼 동작합니다. **고치지 않아도 되는 변경입니다.**
94
+ - `__str__` 라벨이 `NUM-PARTITION` 에서 `NUM-SEGMENT` 로 바뀝니다. 이 출력을 정규식으로 읽는 곳이 있으면 그곳만 봐 주세요.
95
+ - **왜 바꾸는지**: 같은 "파티션" 이라는 말이 토픽과 큐에서 **정반대** 를 뜻하고 있었습니다.
96
+
97
+ | 말 | 뜻 |
98
+ |---|---|
99
+ | 파티션 | **분산 처리 단위** (토픽. 리더 · 팔로워가 붙는다) |
100
+ | 세그먼트 | **한 노드 안의 저장 칸** (큐. 파일 1~N, 메모리, 공유메모리) |
101
+
102
+ 토픽의 `PARTITIONS` 와 큐의 `PARTITION` 이 한 글자 차이로 서로 다른 개념이었습니다. 엔진이 큐에 진짜 분산 파티션을
103
+ 들이기 전에 옛 이름을 비워 두는 것입니다.
104
+ - **와이어는 달라지지 않습니다.** 큐 속성 직렬화는 위치 기반 고정폭이라 **속성 이름이 실리지 않습니다.** 어느 이름으로
105
+ 넣든 나가는 2200바이트(구엔진용 4096 레이아웃도)가 같습니다. 그래서 이 판은 **엔진 판을 가리지 않습니다.**
106
+ - **엔진 쪽 이름도 같이 바뀝니다**(ilsc `PARTITION(n)` -> `SEGMENT(n)`, `VIEW QUEUE` 머리글, 컨피그 XML
107
+ `Storage/@NumberOfPartition` -> `@NumberOfSegment`). 엔진도 옛 이름을 계속 받습니다.
108
+ - ★ **ilsc 에서 `SEGMENT` 를 쓰려면 엔진도 같이 올려야 합니다.** 클라이언트만 올린 환경에서는 엔진이 그 키워드를
109
+ 모릅니다 - 그때도 큐는 정상 동작하고, ilsc 에서 `PARTITION` 을 쓰면 됩니다.
110
+ - **큐 실시간 정보의 "파티션" 목록도 같이 바뀝니다.** `getQueueRealTimeInfo()` 가 돌려주는
111
+ `ILQueueRealTimeInfo` 의 `partitions` 가 **`segments`** 가 되고, 항목 클래스 `PartitionItem` 은 **`SegmentItem`** 이 됩니다.
112
+ - 여기도 **옛 이름이 그대로 돕니다.** `partitions` 는 같은 목록을 가리키는 별칭이고(`getPartitions()` / `setPartitions()` 포함),
113
+ `PartitionItem` 은 `SegmentItem` 과 **같은 클래스 객체**라 `isinstance` 도 전처럼 통합니다.
114
+ - ★ **토픽의 `getPartitions()` 와는 뜻이 다릅니다.** 지금까지 두 클래스에서 **같은 이름이 정반대**를 뜻하고 있었습니다 -
115
+ 토픽 쪽은 분산 처리 단위, 큐 실시간 정보 쪽은 한 노드 안의 저장 칸입니다. 이번 개명의 목적이 바로 이것입니다.
116
+ - `__str__` 머리글이 `Partitions ---` 에서 `Segments ---` 로 바뀝니다(엔진 `VIEW QUEUE` 가 `SEGMENTS(` 로 나가는 것과 맞춥니다).
117
+ - `ILC.MIMQ_VO_SEGMENT_ITEM_LEN` 이 생기고 `ILC.MIMQ_VO_PARTITION_ITEM_LEN` 은 같은 값(128)의 별칭으로 남습니다.
118
+ - **자바 클라이언트는 클래스 이름을 바꾸지 않습니다**(`PartitionItem` 유지, `getSegments()` 추가). 자바는 제네릭이 불변이라
119
+ `ArrayList<PartitionItem>` 을 별칭으로 덮을 수 없고, 사본으로 옛 접근자를 만들면 목록 수정이 조용히 사라지기 때문입니다.
120
+ 파이썬은 클래스 별칭이 완전해서 이런 제약이 없습니다.
121
+ - **없어진 이름은 하나도 없습니다.** 이 판은 **추가와 별칭뿐**입니다.
122
+ - **디스크 파일 이름은 그대로입니다** (`QUEUE.P001`). 저장 레이아웃 자체라 바꾸지 않습니다.
123
+
63
124
  ## 0.14.0 변경 - 소켓 keepalive 탐침 타이머, NIO 커넥터 수신 기한 정합 (자바 v2.10.0 과 같음)
64
125
 
65
126
  - **연결 소켓에 keepalive 탐침 타이머를 겁니다(유휴 60초 + 10초 간격 x 6회).** 엔진이 쓰는 값과 같습니다.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jetstream-api"
7
- version = "0.14.0"
7
+ version = "0.16.0"
8
8
  description = "Python client API for iLink M.O.M. (Message Oriented Middleware)"
9
9
  authors = [{name = "snowjeans"}]
10
10
  readme = "README.md"
File without changes