py-alaska 0.1.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.
- py_alaska-0.1.0/LICENSE +21 -0
- py_alaska-0.1.0/MANIFEST.in +25 -0
- py_alaska-0.1.0/PKG-INFO +263 -0
- py_alaska-0.1.0/README.md +222 -0
- py_alaska-0.1.0/pyproject.toml +61 -0
- py_alaska-0.1.0/requirements.txt +14 -0
- py_alaska-0.1.0/setup.cfg +4 -0
- py_alaska-0.1.0/setup.py +13 -0
- py_alaska-0.1.0/src/py_alaska/SmBlock.py +263 -0
- py_alaska-0.1.0/src/py_alaska/__init__.py +63 -0
- py_alaska-0.1.0/src/py_alaska/div_logo.png +0 -0
- py_alaska-0.1.0/src/py_alaska/gconfig.py +1241 -0
- py_alaska-0.1.0/src/py_alaska/imi_camera.py +391 -0
- py_alaska-0.1.0/src/py_alaska/tab_camera.py +730 -0
- py_alaska-0.1.0/src/py_alaska/task_manager.py +661 -0
- py_alaska-0.1.0/src/py_alaska/task_monitor.py +1533 -0
- py_alaska-0.1.0/src/py_alaska/task_performance.py +550 -0
- py_alaska-0.1.0/src/py_alaska/task_signal.py +238 -0
- py_alaska-0.1.0/src/py_alaska.egg-info/PKG-INFO +263 -0
- py_alaska-0.1.0/src/py_alaska.egg-info/SOURCES.txt +21 -0
- py_alaska-0.1.0/src/py_alaska.egg-info/dependency_links.txt +1 -0
- py_alaska-0.1.0/src/py_alaska.egg-info/requires.txt +17 -0
- py_alaska-0.1.0/src/py_alaska.egg-info/top_level.txt +1 -0
py_alaska-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DivisionVision
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Include documentation
|
|
2
|
+
include LICENSE
|
|
3
|
+
include README.md
|
|
4
|
+
include requirements.txt
|
|
5
|
+
|
|
6
|
+
# Include package data
|
|
7
|
+
recursive-include src/py_alaska *.py *.png *.json
|
|
8
|
+
|
|
9
|
+
# Exclude development files
|
|
10
|
+
exclude .gitignore
|
|
11
|
+
exclude .pre-commit-config.yaml
|
|
12
|
+
recursive-exclude * __pycache__
|
|
13
|
+
recursive-exclude * *.py[cod]
|
|
14
|
+
recursive-exclude * *.so
|
|
15
|
+
recursive-exclude * .DS_Store
|
|
16
|
+
|
|
17
|
+
# Exclude test and example directories
|
|
18
|
+
prune example
|
|
19
|
+
prune doc
|
|
20
|
+
prune tests
|
|
21
|
+
prune .git
|
|
22
|
+
prune .github
|
|
23
|
+
prune dist
|
|
24
|
+
prune build
|
|
25
|
+
prune *.egg-info
|
py_alaska-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: py-alaska
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ALASKA - Multiprocess Task Management Framework for Python
|
|
5
|
+
Author-email: DivisionVision <info@division.co.kr>
|
|
6
|
+
Maintainer-email: DivisionVision <info@division.co.kr>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/divisionvision/alaska
|
|
9
|
+
Project-URL: Documentation, https://github.com/divisionvision/alaska#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/divisionvision/alaska.git
|
|
11
|
+
Project-URL: Issues, https://github.com/divisionvision/alaska/issues
|
|
12
|
+
Keywords: multiprocess,task,rmi,ipc,monitoring,shared-memory
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
24
|
+
Requires-Python: >=3.8
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy>=1.20.0
|
|
28
|
+
Provides-Extra: monitor
|
|
29
|
+
Requires-Dist: psutil>=5.8.0; extra == "monitor"
|
|
30
|
+
Provides-Extra: camera
|
|
31
|
+
Requires-Dist: PySide6>=6.0.0; extra == "camera"
|
|
32
|
+
Provides-Extra: all
|
|
33
|
+
Requires-Dist: psutil>=5.8.0; extra == "all"
|
|
34
|
+
Requires-Dist: PySide6>=6.0.0; extra == "all"
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
38
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
39
|
+
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# ALASKA
|
|
43
|
+
|
|
44
|
+
**A**dvanced **L**ightweight **A**synchronous **S**ervice **K**ernel for **A**pplications
|
|
45
|
+
|
|
46
|
+
[](https://badge.fury.io/py/py-alaska)
|
|
47
|
+
[](https://pypi.org/project/py-alaska/)
|
|
48
|
+
[](https://opensource.org/licenses/MIT)
|
|
49
|
+
|
|
50
|
+
A Python framework for building multiprocess task management systems with RMI (Remote Method Invocation), shared memory, and real-time monitoring.
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
- **Multiprocess Task Management**: Run tasks as separate processes or threads
|
|
55
|
+
- **RMI (Remote Method Invocation)**: Call methods across processes seamlessly
|
|
56
|
+
- **Shared Memory (SmBlock)**: Zero-copy image/data sharing between processes
|
|
57
|
+
- **Signal/Broker Pattern**: Pub/sub messaging between tasks
|
|
58
|
+
- **Web Monitoring Dashboard**: Real-time HTTP-based monitoring UI
|
|
59
|
+
- **Performance Metrics**: IPC/FUNC timing statistics with sliding window
|
|
60
|
+
- **Auto-restart**: Automatic task recovery on failure
|
|
61
|
+
- **JSON Configuration**: Flexible configuration with injection support
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Basic installation
|
|
67
|
+
pip install py-alaska
|
|
68
|
+
|
|
69
|
+
# With monitoring support (psutil)
|
|
70
|
+
pip install py-alaska[monitor]
|
|
71
|
+
|
|
72
|
+
# With camera/GUI support (PySide6)
|
|
73
|
+
pip install py-alaska[camera]
|
|
74
|
+
|
|
75
|
+
# Full installation
|
|
76
|
+
pip install py-alaska[all]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Quick Start
|
|
80
|
+
|
|
81
|
+
### 1. Define a Task
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from py_alaska import TaskClass
|
|
85
|
+
|
|
86
|
+
@TaskClass(name="my_task", mode="process", restart=True)
|
|
87
|
+
class MyTask:
|
|
88
|
+
def __init__(self):
|
|
89
|
+
self.task = None # Injected by framework
|
|
90
|
+
self.counter = 0
|
|
91
|
+
|
|
92
|
+
def increment(self, value: int) -> int:
|
|
93
|
+
"""RMI method: can be called from other tasks"""
|
|
94
|
+
self.counter += value
|
|
95
|
+
return self.counter
|
|
96
|
+
|
|
97
|
+
def get_count(self) -> int:
|
|
98
|
+
"""RMI method: query current count"""
|
|
99
|
+
return self.counter
|
|
100
|
+
|
|
101
|
+
def task_loop(self):
|
|
102
|
+
"""Main loop: runs continuously"""
|
|
103
|
+
while not self.task.should_stop():
|
|
104
|
+
# Do work here
|
|
105
|
+
pass
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 2. Create Configuration (config.json)
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"app_info": {
|
|
113
|
+
"name": "MyApp",
|
|
114
|
+
"version": "1.0.0",
|
|
115
|
+
"id": "myapp_001"
|
|
116
|
+
},
|
|
117
|
+
"task_config": {
|
|
118
|
+
"_monitor": {
|
|
119
|
+
"port": 7000,
|
|
120
|
+
"exit_hook": true
|
|
121
|
+
},
|
|
122
|
+
"worker/my_task": {
|
|
123
|
+
"counter": 0
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 3. Run the Application
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from py_alaska import TaskManager, gconfig
|
|
133
|
+
import my_task # Import to register TaskClass
|
|
134
|
+
|
|
135
|
+
def main():
|
|
136
|
+
gconfig.load("config.json")
|
|
137
|
+
|
|
138
|
+
manager = TaskManager(gconfig)
|
|
139
|
+
manager.start_all()
|
|
140
|
+
|
|
141
|
+
# Access via RMI
|
|
142
|
+
worker = manager.get_client("worker")
|
|
143
|
+
result = worker.increment(10)
|
|
144
|
+
print(f"Counter: {result}")
|
|
145
|
+
|
|
146
|
+
# Web monitor at http://localhost:7000
|
|
147
|
+
import time
|
|
148
|
+
time.sleep(3600)
|
|
149
|
+
|
|
150
|
+
manager.stop_all()
|
|
151
|
+
|
|
152
|
+
if __name__ == "__main__":
|
|
153
|
+
main()
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Architecture
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
160
|
+
│ TaskManager │
|
|
161
|
+
├─────────────────────────────────────────────────────────────┤
|
|
162
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
163
|
+
│ │ Task A │ │ Task B │ │ Task C │ │
|
|
164
|
+
│ │ (Process) │ │ (Process) │ │ (Thread) │ │
|
|
165
|
+
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
166
|
+
│ │ │ │ │
|
|
167
|
+
│ └────────────────┼────────────────┘ │
|
|
168
|
+
│ │ │
|
|
169
|
+
│ ┌─────┴─────┐ │
|
|
170
|
+
│ │ RMI Bus │ │
|
|
171
|
+
│ │ (Queue) │ │
|
|
172
|
+
│ └─────┬─────┘ │
|
|
173
|
+
│ │ │
|
|
174
|
+
│ ┌─────┴─────┐ │
|
|
175
|
+
│ │ SmBlock │ │
|
|
176
|
+
│ │ (Shared) │ │
|
|
177
|
+
│ └───────────┘ │
|
|
178
|
+
├─────────────────────────────────────────────────────────────┤
|
|
179
|
+
│ TaskMonitor │
|
|
180
|
+
│ HTTP :7000 │
|
|
181
|
+
└─────────────────────────────────────────────────────────────┘
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Core Components
|
|
185
|
+
|
|
186
|
+
| Component | Description |
|
|
187
|
+
|-----------|-------------|
|
|
188
|
+
| `TaskManager` | Main orchestrator for all tasks |
|
|
189
|
+
| `TaskClass` | Decorator to define a task |
|
|
190
|
+
| `RmiClient` | Client for calling remote methods |
|
|
191
|
+
| `SmBlock` | Shared memory block pool for zero-copy data sharing |
|
|
192
|
+
| `Signal/SignalBroker` | Pub/sub messaging system |
|
|
193
|
+
| `TaskMonitor` | HTTP-based web monitoring dashboard |
|
|
194
|
+
| `GConfig` | Global configuration management |
|
|
195
|
+
|
|
196
|
+
## API Reference
|
|
197
|
+
|
|
198
|
+
### TaskClass Decorator
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
@TaskClass(
|
|
202
|
+
name="task_name", # Unique task identifier
|
|
203
|
+
mode="process", # "process" or "thread"
|
|
204
|
+
restart=True, # Auto-restart on failure
|
|
205
|
+
restart_delay=3.0, # Delay before restart (seconds)
|
|
206
|
+
)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### RMI Methods
|
|
210
|
+
|
|
211
|
+
Any public method in a TaskClass becomes an RMI method:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
# In Task A
|
|
215
|
+
def calculate(self, x: int, y: int) -> int:
|
|
216
|
+
return x + y
|
|
217
|
+
|
|
218
|
+
# From Task B or main process
|
|
219
|
+
client = manager.get_client("task_a")
|
|
220
|
+
result = client.calculate(10, 20) # Returns 30
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### SmBlock (Shared Memory)
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
# Configuration
|
|
227
|
+
"_smblock": {
|
|
228
|
+
"image_pool": {"shape": [1024, 1024, 3], "maxsize": 100}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
# In task
|
|
232
|
+
index = self.smblock.malloc() # Allocate block
|
|
233
|
+
image = self.smblock.get(index) # Get numpy array
|
|
234
|
+
image[:] = frame # Write data
|
|
235
|
+
self.smblock.mfree(index) # Release block
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Monitoring
|
|
239
|
+
|
|
240
|
+
Access the web dashboard at `http://localhost:7000` (configurable port).
|
|
241
|
+
|
|
242
|
+
**Features:**
|
|
243
|
+
- Real-time task status (alive/stopped)
|
|
244
|
+
- RMI call statistics (count, timing)
|
|
245
|
+
- CPU/Memory usage per task
|
|
246
|
+
- SmBlock pool utilization
|
|
247
|
+
- Configuration editor
|
|
248
|
+
- Performance metrics (IPC/FUNC time)
|
|
249
|
+
|
|
250
|
+
## Requirements
|
|
251
|
+
|
|
252
|
+
- Python >= 3.8
|
|
253
|
+
- numpy >= 1.20.0
|
|
254
|
+
- psutil >= 5.8.0 (optional, for monitoring)
|
|
255
|
+
- PySide6 >= 6.0.0 (optional, for camera/GUI)
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
260
|
+
|
|
261
|
+
## Contributing
|
|
262
|
+
|
|
263
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# ALASKA
|
|
2
|
+
|
|
3
|
+
**A**dvanced **L**ightweight **A**synchronous **S**ervice **K**ernel for **A**pplications
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/py/py-alaska)
|
|
6
|
+
[](https://pypi.org/project/py-alaska/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
A Python framework for building multiprocess task management systems with RMI (Remote Method Invocation), shared memory, and real-time monitoring.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Multiprocess Task Management**: Run tasks as separate processes or threads
|
|
14
|
+
- **RMI (Remote Method Invocation)**: Call methods across processes seamlessly
|
|
15
|
+
- **Shared Memory (SmBlock)**: Zero-copy image/data sharing between processes
|
|
16
|
+
- **Signal/Broker Pattern**: Pub/sub messaging between tasks
|
|
17
|
+
- **Web Monitoring Dashboard**: Real-time HTTP-based monitoring UI
|
|
18
|
+
- **Performance Metrics**: IPC/FUNC timing statistics with sliding window
|
|
19
|
+
- **Auto-restart**: Automatic task recovery on failure
|
|
20
|
+
- **JSON Configuration**: Flexible configuration with injection support
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Basic installation
|
|
26
|
+
pip install py-alaska
|
|
27
|
+
|
|
28
|
+
# With monitoring support (psutil)
|
|
29
|
+
pip install py-alaska[monitor]
|
|
30
|
+
|
|
31
|
+
# With camera/GUI support (PySide6)
|
|
32
|
+
pip install py-alaska[camera]
|
|
33
|
+
|
|
34
|
+
# Full installation
|
|
35
|
+
pip install py-alaska[all]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
### 1. Define a Task
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from py_alaska import TaskClass
|
|
44
|
+
|
|
45
|
+
@TaskClass(name="my_task", mode="process", restart=True)
|
|
46
|
+
class MyTask:
|
|
47
|
+
def __init__(self):
|
|
48
|
+
self.task = None # Injected by framework
|
|
49
|
+
self.counter = 0
|
|
50
|
+
|
|
51
|
+
def increment(self, value: int) -> int:
|
|
52
|
+
"""RMI method: can be called from other tasks"""
|
|
53
|
+
self.counter += value
|
|
54
|
+
return self.counter
|
|
55
|
+
|
|
56
|
+
def get_count(self) -> int:
|
|
57
|
+
"""RMI method: query current count"""
|
|
58
|
+
return self.counter
|
|
59
|
+
|
|
60
|
+
def task_loop(self):
|
|
61
|
+
"""Main loop: runs continuously"""
|
|
62
|
+
while not self.task.should_stop():
|
|
63
|
+
# Do work here
|
|
64
|
+
pass
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 2. Create Configuration (config.json)
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"app_info": {
|
|
72
|
+
"name": "MyApp",
|
|
73
|
+
"version": "1.0.0",
|
|
74
|
+
"id": "myapp_001"
|
|
75
|
+
},
|
|
76
|
+
"task_config": {
|
|
77
|
+
"_monitor": {
|
|
78
|
+
"port": 7000,
|
|
79
|
+
"exit_hook": true
|
|
80
|
+
},
|
|
81
|
+
"worker/my_task": {
|
|
82
|
+
"counter": 0
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Run the Application
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from py_alaska import TaskManager, gconfig
|
|
92
|
+
import my_task # Import to register TaskClass
|
|
93
|
+
|
|
94
|
+
def main():
|
|
95
|
+
gconfig.load("config.json")
|
|
96
|
+
|
|
97
|
+
manager = TaskManager(gconfig)
|
|
98
|
+
manager.start_all()
|
|
99
|
+
|
|
100
|
+
# Access via RMI
|
|
101
|
+
worker = manager.get_client("worker")
|
|
102
|
+
result = worker.increment(10)
|
|
103
|
+
print(f"Counter: {result}")
|
|
104
|
+
|
|
105
|
+
# Web monitor at http://localhost:7000
|
|
106
|
+
import time
|
|
107
|
+
time.sleep(3600)
|
|
108
|
+
|
|
109
|
+
manager.stop_all()
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
main()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Architecture
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
119
|
+
│ TaskManager │
|
|
120
|
+
├─────────────────────────────────────────────────────────────┤
|
|
121
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
122
|
+
│ │ Task A │ │ Task B │ │ Task C │ │
|
|
123
|
+
│ │ (Process) │ │ (Process) │ │ (Thread) │ │
|
|
124
|
+
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
125
|
+
│ │ │ │ │
|
|
126
|
+
│ └────────────────┼────────────────┘ │
|
|
127
|
+
│ │ │
|
|
128
|
+
│ ┌─────┴─────┐ │
|
|
129
|
+
│ │ RMI Bus │ │
|
|
130
|
+
│ │ (Queue) │ │
|
|
131
|
+
│ └─────┬─────┘ │
|
|
132
|
+
│ │ │
|
|
133
|
+
│ ┌─────┴─────┐ │
|
|
134
|
+
│ │ SmBlock │ │
|
|
135
|
+
│ │ (Shared) │ │
|
|
136
|
+
│ └───────────┘ │
|
|
137
|
+
├─────────────────────────────────────────────────────────────┤
|
|
138
|
+
│ TaskMonitor │
|
|
139
|
+
│ HTTP :7000 │
|
|
140
|
+
└─────────────────────────────────────────────────────────────┘
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Core Components
|
|
144
|
+
|
|
145
|
+
| Component | Description |
|
|
146
|
+
|-----------|-------------|
|
|
147
|
+
| `TaskManager` | Main orchestrator for all tasks |
|
|
148
|
+
| `TaskClass` | Decorator to define a task |
|
|
149
|
+
| `RmiClient` | Client for calling remote methods |
|
|
150
|
+
| `SmBlock` | Shared memory block pool for zero-copy data sharing |
|
|
151
|
+
| `Signal/SignalBroker` | Pub/sub messaging system |
|
|
152
|
+
| `TaskMonitor` | HTTP-based web monitoring dashboard |
|
|
153
|
+
| `GConfig` | Global configuration management |
|
|
154
|
+
|
|
155
|
+
## API Reference
|
|
156
|
+
|
|
157
|
+
### TaskClass Decorator
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
@TaskClass(
|
|
161
|
+
name="task_name", # Unique task identifier
|
|
162
|
+
mode="process", # "process" or "thread"
|
|
163
|
+
restart=True, # Auto-restart on failure
|
|
164
|
+
restart_delay=3.0, # Delay before restart (seconds)
|
|
165
|
+
)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### RMI Methods
|
|
169
|
+
|
|
170
|
+
Any public method in a TaskClass becomes an RMI method:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
# In Task A
|
|
174
|
+
def calculate(self, x: int, y: int) -> int:
|
|
175
|
+
return x + y
|
|
176
|
+
|
|
177
|
+
# From Task B or main process
|
|
178
|
+
client = manager.get_client("task_a")
|
|
179
|
+
result = client.calculate(10, 20) # Returns 30
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### SmBlock (Shared Memory)
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
# Configuration
|
|
186
|
+
"_smblock": {
|
|
187
|
+
"image_pool": {"shape": [1024, 1024, 3], "maxsize": 100}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# In task
|
|
191
|
+
index = self.smblock.malloc() # Allocate block
|
|
192
|
+
image = self.smblock.get(index) # Get numpy array
|
|
193
|
+
image[:] = frame # Write data
|
|
194
|
+
self.smblock.mfree(index) # Release block
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Monitoring
|
|
198
|
+
|
|
199
|
+
Access the web dashboard at `http://localhost:7000` (configurable port).
|
|
200
|
+
|
|
201
|
+
**Features:**
|
|
202
|
+
- Real-time task status (alive/stopped)
|
|
203
|
+
- RMI call statistics (count, timing)
|
|
204
|
+
- CPU/Memory usage per task
|
|
205
|
+
- SmBlock pool utilization
|
|
206
|
+
- Configuration editor
|
|
207
|
+
- Performance metrics (IPC/FUNC time)
|
|
208
|
+
|
|
209
|
+
## Requirements
|
|
210
|
+
|
|
211
|
+
- Python >= 3.8
|
|
212
|
+
- numpy >= 1.20.0
|
|
213
|
+
- psutil >= 5.8.0 (optional, for monitoring)
|
|
214
|
+
- PySide6 >= 6.0.0 (optional, for camera/GUI)
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
219
|
+
|
|
220
|
+
## Contributing
|
|
221
|
+
|
|
222
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "py-alaska"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "ALASKA - Multiprocess Task Management Framework for Python"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "DivisionVision", email = "info@division.co.kr"}
|
|
13
|
+
]
|
|
14
|
+
maintainers = [
|
|
15
|
+
{name = "DivisionVision", email = "info@division.co.kr"}
|
|
16
|
+
]
|
|
17
|
+
requires-python = ">=3.8"
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 4 - Beta",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.8",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
29
|
+
"Topic :: System :: Distributed Computing",
|
|
30
|
+
]
|
|
31
|
+
keywords = ["multiprocess", "task", "rmi", "ipc", "monitoring", "shared-memory"]
|
|
32
|
+
|
|
33
|
+
dependencies = [
|
|
34
|
+
"numpy>=1.20.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
monitor = ["psutil>=5.8.0"]
|
|
39
|
+
camera = ["PySide6>=6.0.0"]
|
|
40
|
+
all = ["psutil>=5.8.0", "PySide6>=6.0.0"]
|
|
41
|
+
dev = [
|
|
42
|
+
"pytest>=7.0.0",
|
|
43
|
+
"pytest-cov>=4.0.0",
|
|
44
|
+
"build>=1.0.0",
|
|
45
|
+
"twine>=4.0.0",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://github.com/divisionvision/alaska"
|
|
50
|
+
Documentation = "https://github.com/divisionvision/alaska#readme"
|
|
51
|
+
Repository = "https://github.com/divisionvision/alaska.git"
|
|
52
|
+
Issues = "https://github.com/divisionvision/alaska/issues"
|
|
53
|
+
|
|
54
|
+
[tool.setuptools]
|
|
55
|
+
package-dir = {"" = "src"}
|
|
56
|
+
|
|
57
|
+
[tool.setuptools.packages.find]
|
|
58
|
+
where = ["src"]
|
|
59
|
+
|
|
60
|
+
[tool.setuptools.package-data]
|
|
61
|
+
py_alaska = ["*.png", "*.json"]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# ALASKA - Core Dependencies
|
|
2
|
+
numpy>=1.20.0
|
|
3
|
+
|
|
4
|
+
# Optional: Monitoring (install with: pip install alaska[monitor])
|
|
5
|
+
# psutil>=5.8.0
|
|
6
|
+
|
|
7
|
+
# Optional: Camera/GUI (install with: pip install alaska[camera])
|
|
8
|
+
# PySide6>=6.0.0
|
|
9
|
+
|
|
10
|
+
# Development Dependencies (install with: pip install alaska[dev])
|
|
11
|
+
# pytest>=7.0.0
|
|
12
|
+
# pytest-cov>=4.0.0
|
|
13
|
+
# build>=1.0.0
|
|
14
|
+
# twine>=4.0.0
|
py_alaska-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
ALASKA - Multiprocess Task Management Framework
|
|
5
|
+
|
|
6
|
+
Backward compatibility setup script.
|
|
7
|
+
Configuration is in pyproject.toml (PEP 517/518).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from setuptools import setup
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
setup()
|