slick-queue-py 2.0.0__tar.gz → 2.3.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.
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/API_DIFFERENCES.md +35 -7
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/CHANGELOG.md +349 -211
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/PKG-INFO +108 -10
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/README.md +107 -9
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/slick_queue_py.egg-info/SOURCES.txt +2 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/slick_queue_py.py +351 -84
- slick_queue_py-2.3.0/tests/test_items_per_slot.py +484 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_modern_format.py +4 -2
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_multi_producer.py +47 -10
- slick_queue_py-2.3.0/tests/test_segment_lifetime.py +410 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_traits.py +10 -14
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.github/FUNDING.yml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.github/workflows/ci.yml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.github/workflows/publish-conda.yml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.github/workflows/publish-pypi.yml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.github/workflows/publish-release.yml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.github/workflows/release.yml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.gitignore +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/.pypirc.template +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/BUILDING.md +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/CMakeLists.txt +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/LICENSE +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/MANIFEST.in +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/atomic_ops.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/atomic_ops_ext.cpp +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/conda.recipe/meta.yaml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/pyproject.toml +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/requirements.txt +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/setup.cfg +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/setup.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/cleanup_shm.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/cpp_consumer.cpp +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/cpp_multi_producer.cpp +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/cpp_producer.cpp +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/cpp_read_last_tester.cpp +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/cpp_work_stealing_consumer.cpp +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/run_test.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_atomic_cursor.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_atomic_ops.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_interop.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_local_mode.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_loss_count.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_queue.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_read_last.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_read_last_interop.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_reset_detection.py +0 -0
- {slick_queue_py-2.0.0 → slick_queue_py-2.3.0}/tests/test_wrap_invariants.py +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This document explains the intentional API differences between the C++ `slick::queue<T>` and Python `SlickQueue` implementations.
|
|
4
4
|
|
|
5
|
-
Both track the same version line; this document describes slick-queue v2.
|
|
5
|
+
Both track the same version line; this document describes slick-queue v2.3.0.
|
|
6
6
|
|
|
7
7
|
## Core Compatibility
|
|
8
8
|
|
|
@@ -26,6 +26,9 @@ slick::queue<uint8_t> q(queue_name);
|
|
|
26
26
|
|
|
27
27
|
// Local memory mode
|
|
28
28
|
slick::queue<uint8_t> q(queue_size); // No shared memory
|
|
29
|
+
|
|
30
|
+
// Minimum of 64 items per reservation (one control slot per 64 items)
|
|
31
|
+
slick::queue<uint8_t> q(queue_size, 64, queue_name);
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
**Python:**
|
|
@@ -38,10 +41,17 @@ q = SlickQueue(name=queue_name, element_size=element_size)
|
|
|
38
41
|
|
|
39
42
|
# Local memory mode
|
|
40
43
|
q = SlickQueue(size=queue_size, element_size=element_size) # No shared memory
|
|
44
|
+
|
|
45
|
+
# Minimum of 64 items per reservation (one control slot per 64 items)
|
|
46
|
+
q = SlickQueue(name=queue_name, size=queue_size, element_size=1, items_per_slot=64)
|
|
41
47
|
```
|
|
42
48
|
|
|
43
49
|
**Rationale:** Python uses keyword arguments for clarity and supports both shared memory and local memory modes.
|
|
44
50
|
|
|
51
|
+
`items_per_slot` is the one place the opener differs: C++ `queue(name)` can only adopt the
|
|
52
|
+
segment's value, while Python's opener also accepts `items_per_slot=` and raises `ValueError`
|
|
53
|
+
if the segment disagrees. Omitting it adopts the segment's value, exactly as C++ does.
|
|
54
|
+
|
|
45
55
|
---
|
|
46
56
|
|
|
47
57
|
### 2. read() Method - Return Value vs. Reference Parameter
|
|
@@ -217,27 +227,44 @@ q[idx][:4] = struct.pack("<i", 42) # Manual packing
|
|
|
217
227
|
{
|
|
218
228
|
slick::queue<T> q(size, "name");
|
|
219
229
|
// ... use queue ...
|
|
220
|
-
|
|
230
|
+
q.remove_shm(); // Coordinator, once no peer will attach again; q's mapping stays valid
|
|
231
|
+
} // Destructor unmaps; it never removes the segment
|
|
232
|
+
|
|
233
|
+
slick::shm::shared_memory::remove("name"); // By name, without a queue - e.g. at startup
|
|
221
234
|
```
|
|
222
235
|
|
|
223
236
|
**Python:**
|
|
224
237
|
```python
|
|
225
238
|
# Option 1: Manual cleanup
|
|
226
|
-
q = SlickQueue(name='name', size=size, element_size=elem_size
|
|
239
|
+
q = SlickQueue(name='name', size=size, element_size=elem_size)
|
|
227
240
|
try:
|
|
228
241
|
# ... use queue ...
|
|
229
242
|
finally:
|
|
230
243
|
q.close()
|
|
231
|
-
q.unlink() # Only
|
|
244
|
+
q.unlink() # Only from the process that coordinates the queue's lifetime
|
|
232
245
|
|
|
233
|
-
# Option 2: Context manager
|
|
234
|
-
with SlickQueue(name='name', size=size, element_size=elem_size
|
|
246
|
+
# Option 2: Context manager - closes, never unlinks
|
|
247
|
+
with SlickQueue(name='name', size=size, element_size=elem_size) as q:
|
|
235
248
|
# ... use queue ...
|
|
236
|
-
pass
|
|
249
|
+
pass
|
|
250
|
+
|
|
251
|
+
SlickQueue.remove('name') # By name, without attaching - e.g. at startup
|
|
237
252
|
```
|
|
238
253
|
|
|
239
254
|
**Rationale:** Python's garbage collection is non-deterministic, so explicit cleanup or context managers are needed.
|
|
240
255
|
|
|
256
|
+
Neither side deletes a segment on its own, matching C++ v2.3.0: not the C++ destructor, and not
|
|
257
|
+
Python's `close()`, context manager or process exit. Python keeps its segments out of
|
|
258
|
+
`multiprocessing`'s resource tracker for this, since the tracker would otherwise unlink them when
|
|
259
|
+
the process exits.
|
|
260
|
+
|
|
261
|
+
| C++ | Python |
|
|
262
|
+
|-----|--------|
|
|
263
|
+
| `remove_shm()` | `remove_shm()` - same contract, unlinks by name on every call |
|
|
264
|
+
| - | `unlink()` - unlinks once, valid after `close()`; a repeat is a no-op |
|
|
265
|
+
| `slick::shm::shared_memory::remove(name)` | `SlickQueue.remove(name)` - also accepts a `/`-prefixed name |
|
|
266
|
+
| `shm_name()` - `""` for a local queue | `get_shm_name()` - `None` for a local queue, `/`-prefixed on POSIX |
|
|
267
|
+
|
|
241
268
|
---
|
|
242
269
|
|
|
243
270
|
## Interoperability Examples
|
|
@@ -329,6 +356,7 @@ int main() {
|
|
|
329
356
|
| Element access | Pointer | `memoryview` | Python memory safety |
|
|
330
357
|
| Type safety | Templates | `struct` module | Language difference |
|
|
331
358
|
| Cleanup | RAII (destructor) | Explicit or context manager | Python GC is non-deterministic |
|
|
359
|
+
| Segment removal | `remove_shm()` | `remove_shm()`, `unlink()`, `SlickQueue.remove()` | Neither side unlinks on its own |
|
|
332
360
|
| `read()` data | `T*` into the ring | `bytes` copy | No safe raw pointers in Python |
|
|
333
361
|
| Overwritten-in-flight data | Caller sees a volatile pointer | Copy may hold a newer record's bytes | Detect with `loss_count()` |
|
|
334
362
|
| Feature configuration | `Traits` template parameter | `traits=` argument | Python has no templates |
|