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.
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/PKG-INFO +62 -1
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/README.md +61 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/__init__.py +3 -1
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/admin.py +7 -7
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/common.py +4 -1
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/properties.py +210 -36
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/PKG-INFO +62 -1
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/pyproject.toml +1 -1
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/LICENSE.txt +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/_codec.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/admintopic.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/connectivity.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/exception.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/msg.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/partitioner.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/pattern.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/producer.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/py.typed +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/qmgr.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/topic.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/ilink/util.py +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/SOURCES.txt +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/dependency_links.txt +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/requires.txt +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/jetstream_api.egg-info/top_level.txt +0 -0
- {jetstream_api-0.14.0 → jetstream_api-0.16.0}/setup.cfg +0 -0
- {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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
5542
|
-
목록**이다 -
|
|
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
|
-
|
|
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
|
|
328
|
-
"""큐
|
|
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): 이
|
|
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.
|
|
440
|
+
if len(ba) < ILC.MIMQ_VO_SEGMENT_ITEM_LEN:
|
|
365
441
|
raise ILDeserializeException(
|
|
366
442
|
"invalid byte array length. fixed : ["
|
|
367
|
-
+ str(ILC.
|
|
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.
|
|
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
|
-
|
|
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`` / ``
|
|
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.
|
|
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.
|
|
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`` / ``
|
|
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.
|
|
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-
|
|
981
|
-
+ str(self.
|
|
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
|
-
|
|
2004
|
-
|
|
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.
|
|
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 =
|
|
2072
|
-
ba_pick_bytes(ba, offset, ILC.
|
|
2245
|
+
item = SegmentItem(
|
|
2246
|
+
ba_pick_bytes(ba, offset, ILC.MIMQ_VO_SEGMENT_ITEM_LEN)
|
|
2073
2247
|
)
|
|
2074
|
-
self.
|
|
2075
|
-
offset += ILC.
|
|
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.
|
|
2091
|
-
buffer_length += len(self.
|
|
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.
|
|
2288
|
+
ba_merge(len(self.segmentInfoList), ba, offset, 5)
|
|
2115
2289
|
offset += 5
|
|
2116
|
-
for item in self.
|
|
2117
|
-
ba_merge(item.get_serialized(), ba, offset, ILC.
|
|
2118
|
-
offset += ILC.
|
|
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 += "
|
|
2142
|
-
for
|
|
2143
|
-
ret += " " + str(
|
|
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:`
|
|
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.
|
|
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.
|
|
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회).** 엔진이 쓰는 값과 같습니다.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|