concurrent-c-node 0.14.0__tar.gz → 0.15.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.
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/PKG-INFO +30 -6
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/README.md +29 -5
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/cc_node/__init__.py +1 -1
- concurrent_c_node-0.15.0/cc_node/benchmarks/__init__.py +1 -0
- concurrent_c_node-0.15.0/cc_node/benchmarks/multi_domain.py +60 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/concurrent_c_node.egg-info/PKG-INFO +30 -6
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/concurrent_c_node.egg-info/SOURCES.txt +2 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/pyproject.toml +3 -2
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/cc_node/broker.cjs +0 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/cc_node/examples/__init__.py +0 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/cc_node/examples/bench_wire.py +0 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/cc_node/examples/use_node.py +0 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/concurrent_c_node.egg-info/dependency_links.txt +0 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/concurrent_c_node.egg-info/top_level.txt +0 -0
- {concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: concurrent-c-node
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: JavaScript and npm packages from Python over the Concurrent-C bridge: one spawned Node child per domain, host-controlled lifetime.
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Repository, https://github.com/sreekotay/concurrent-c
|
|
@@ -62,6 +62,7 @@ event-loop or GIL between them.
|
|
|
62
62
|
pip install concurrent-c-node # needs node on PATH (or point at one)
|
|
63
63
|
python -m cc_node.examples.use_node
|
|
64
64
|
python -m cc_node.examples.bench_wire
|
|
65
|
+
python -m cc_node.benchmarks.multi_domain # N children, thread-fanned
|
|
65
66
|
```
|
|
66
67
|
|
|
67
68
|
## Measured (separate-process wire)
|
|
@@ -186,7 +187,9 @@ JS Promise you must await.
|
|
|
186
187
|
**Wire cost vs tiny work.** Round trip is ~100µs class; a one-line JS
|
|
187
188
|
helper on three numbers loses to pure Python. Prefer Python (or a native
|
|
188
189
|
CC module) for small/hot work; use the bridge when Node/npm owns the
|
|
189
|
-
kernel (crypto, parsers, large buffers via shm).
|
|
190
|
+
kernel (crypto, parsers, large buffers via shm). Multi-core: fan across
|
|
191
|
+
`create()` handles from threads —
|
|
192
|
+
`python -m cc_node.benchmarks.multi_domain` (~2.8× on 3 domains here).
|
|
190
193
|
|
|
191
194
|
**Crash isolation, not a sandbox.** The child inherits your environment
|
|
192
195
|
and privileges — do not evaluate untrusted JavaScript. `destroy()` is
|
|
@@ -214,16 +217,37 @@ speaks, from CC.
|
|
|
214
217
|
|
|
215
218
|
## Publishing
|
|
216
219
|
|
|
217
|
-
|
|
220
|
+
**Preferred — PyPI Trusted Publishing (OIDC) from CI** (no API token):
|
|
221
|
+
|
|
222
|
+
1. One-time on
|
|
223
|
+
[Publishing settings](https://pypi.org/manage/project/concurrent-c-node/settings/publishing/):
|
|
224
|
+
- Owner `sreekotay`, repository `concurrent-c`
|
|
225
|
+
- Workflow name `publish-cc-node.yml`
|
|
226
|
+
- Environment name `pypi`
|
|
227
|
+
2. Create a GitHub Environment named `pypi` (optional reviewers encouraged).
|
|
228
|
+
3. Bump `version` in `pyproject.toml`, commit + push, then:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
gh workflow run publish-cc-node.yml
|
|
232
|
+
# or: git tag cc-node-vX.Y.Z && git push --tags
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Local pack / npm sibling (PyPI defaults to CI OIDC after npm):
|
|
218
236
|
|
|
219
237
|
```
|
|
220
|
-
./scripts/publish_bridges.sh
|
|
221
|
-
|
|
238
|
+
./scripts/publish_bridges.sh --publish --minor
|
|
239
|
+
# npm is live; then commit+push bumps and:
|
|
240
|
+
gh workflow run publish-cc-node.yml
|
|
241
|
+
|
|
242
|
+
# local twine fallback:
|
|
243
|
+
./scripts/publish_bridges.sh --publish --minor --pypi-twine
|
|
222
244
|
```
|
|
223
245
|
|
|
224
246
|
A worked tour (builtin Node modules, chains, callbacks, thenables,
|
|
225
247
|
buffers — no npm install needed):
|
|
226
|
-
`python -m cc_node.examples.use_node`.
|
|
248
|
+
`python -m cc_node.examples.use_node`. Wire RTT / shm:
|
|
249
|
+
`python -m cc_node.examples.bench_wire`. Multi-core domains (threads):
|
|
250
|
+
`python -m cc_node.benchmarks.multi_domain`.
|
|
227
251
|
|
|
228
252
|
Adversarial multi-child storm (escaped closures, cooperative
|
|
229
253
|
fanout-destroy, abort inject, handle-leak / RSS soaks):
|
|
@@ -51,6 +51,7 @@ event-loop or GIL between them.
|
|
|
51
51
|
pip install concurrent-c-node # needs node on PATH (or point at one)
|
|
52
52
|
python -m cc_node.examples.use_node
|
|
53
53
|
python -m cc_node.examples.bench_wire
|
|
54
|
+
python -m cc_node.benchmarks.multi_domain # N children, thread-fanned
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
## Measured (separate-process wire)
|
|
@@ -175,7 +176,9 @@ JS Promise you must await.
|
|
|
175
176
|
**Wire cost vs tiny work.** Round trip is ~100µs class; a one-line JS
|
|
176
177
|
helper on three numbers loses to pure Python. Prefer Python (or a native
|
|
177
178
|
CC module) for small/hot work; use the bridge when Node/npm owns the
|
|
178
|
-
kernel (crypto, parsers, large buffers via shm).
|
|
179
|
+
kernel (crypto, parsers, large buffers via shm). Multi-core: fan across
|
|
180
|
+
`create()` handles from threads —
|
|
181
|
+
`python -m cc_node.benchmarks.multi_domain` (~2.8× on 3 domains here).
|
|
179
182
|
|
|
180
183
|
**Crash isolation, not a sandbox.** The child inherits your environment
|
|
181
184
|
and privileges — do not evaluate untrusted JavaScript. `destroy()` is
|
|
@@ -203,16 +206,37 @@ speaks, from CC.
|
|
|
203
206
|
|
|
204
207
|
## Publishing
|
|
205
208
|
|
|
206
|
-
|
|
209
|
+
**Preferred — PyPI Trusted Publishing (OIDC) from CI** (no API token):
|
|
210
|
+
|
|
211
|
+
1. One-time on
|
|
212
|
+
[Publishing settings](https://pypi.org/manage/project/concurrent-c-node/settings/publishing/):
|
|
213
|
+
- Owner `sreekotay`, repository `concurrent-c`
|
|
214
|
+
- Workflow name `publish-cc-node.yml`
|
|
215
|
+
- Environment name `pypi`
|
|
216
|
+
2. Create a GitHub Environment named `pypi` (optional reviewers encouraged).
|
|
217
|
+
3. Bump `version` in `pyproject.toml`, commit + push, then:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
gh workflow run publish-cc-node.yml
|
|
221
|
+
# or: git tag cc-node-vX.Y.Z && git push --tags
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Local pack / npm sibling (PyPI defaults to CI OIDC after npm):
|
|
207
225
|
|
|
208
226
|
```
|
|
209
|
-
./scripts/publish_bridges.sh
|
|
210
|
-
|
|
227
|
+
./scripts/publish_bridges.sh --publish --minor
|
|
228
|
+
# npm is live; then commit+push bumps and:
|
|
229
|
+
gh workflow run publish-cc-node.yml
|
|
230
|
+
|
|
231
|
+
# local twine fallback:
|
|
232
|
+
./scripts/publish_bridges.sh --publish --minor --pypi-twine
|
|
211
233
|
```
|
|
212
234
|
|
|
213
235
|
A worked tour (builtin Node modules, chains, callbacks, thenables,
|
|
214
236
|
buffers — no npm install needed):
|
|
215
|
-
`python -m cc_node.examples.use_node`.
|
|
237
|
+
`python -m cc_node.examples.use_node`. Wire RTT / shm:
|
|
238
|
+
`python -m cc_node.examples.bench_wire`. Multi-core domains (threads):
|
|
239
|
+
`python -m cc_node.benchmarks.multi_domain`.
|
|
216
240
|
|
|
217
241
|
Adversarial multi-child storm (escaped closures, cooperative
|
|
218
242
|
fanout-destroy, abort inject, handle-leak / RSS soaks):
|
|
@@ -30,7 +30,7 @@ import subprocess
|
|
|
30
30
|
import tempfile
|
|
31
31
|
|
|
32
32
|
__all__ = ["create", "JsError", "JsHandle", "__version__"]
|
|
33
|
-
__version__ = "0.
|
|
33
|
+
__version__ = "0.13.0"
|
|
34
34
|
|
|
35
35
|
# Typed buffers cross as typed arrays; big ones spill through shared
|
|
36
36
|
# memory (tmpfs where available) — one memcpy per side, receiver
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Measurement scripts for concurrent-c-node (RESULT lines, machine-comparable).
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""N node children on N cores — measured with real overlap.
|
|
2
|
+
|
|
3
|
+
python -m cc_node.benchmarks.multi_domain
|
|
4
|
+
|
|
5
|
+
Wire RTT / shm live in ``cc_node.examples.bench_wire``. This file only
|
|
6
|
+
answers the multi-domain question: sequential calls on one child vs the
|
|
7
|
+
same work fanned across threads into separate children.
|
|
8
|
+
"""
|
|
9
|
+
import time
|
|
10
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
11
|
+
|
|
12
|
+
import cc_node
|
|
13
|
+
|
|
14
|
+
WORK = """
|
|
15
|
+
(iterations) => {
|
|
16
|
+
let s = 0;
|
|
17
|
+
for (let i = 0; i < iterations; i++)
|
|
18
|
+
s += Math.sqrt(i) * Math.sin(i / 1000);
|
|
19
|
+
return s;
|
|
20
|
+
}
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def main():
|
|
25
|
+
n_dom = 3
|
|
26
|
+
iters = 40_000_000
|
|
27
|
+
|
|
28
|
+
with cc_node.create() as js:
|
|
29
|
+
f = js.eval(WORK)
|
|
30
|
+
f(iters // 20)
|
|
31
|
+
t0 = time.perf_counter()
|
|
32
|
+
for _ in range(n_dom):
|
|
33
|
+
f(iters)
|
|
34
|
+
seq = time.perf_counter() - t0
|
|
35
|
+
print("RESULT seq_s %.3f" % seq)
|
|
36
|
+
|
|
37
|
+
domains = [cc_node.create() for _ in range(n_dom)]
|
|
38
|
+
try:
|
|
39
|
+
fns = [d.eval(WORK) for d in domains]
|
|
40
|
+
for f in fns:
|
|
41
|
+
f(iters // 20)
|
|
42
|
+
|
|
43
|
+
def run(f):
|
|
44
|
+
return f(iters)
|
|
45
|
+
|
|
46
|
+
t0 = time.perf_counter()
|
|
47
|
+
with ThreadPoolExecutor(max_workers=n_dom) as pool:
|
|
48
|
+
list(pool.map(run, fns))
|
|
49
|
+
par = time.perf_counter() - t0
|
|
50
|
+
finally:
|
|
51
|
+
for d in domains:
|
|
52
|
+
d.destroy()
|
|
53
|
+
|
|
54
|
+
print("RESULT par_s %.3f" % par)
|
|
55
|
+
print("RESULT speedup %.2f" % (seq / par if par else 0))
|
|
56
|
+
print("done")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: concurrent-c-node
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: JavaScript and npm packages from Python over the Concurrent-C bridge: one spawned Node child per domain, host-controlled lifetime.
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Repository, https://github.com/sreekotay/concurrent-c
|
|
@@ -62,6 +62,7 @@ event-loop or GIL between them.
|
|
|
62
62
|
pip install concurrent-c-node # needs node on PATH (or point at one)
|
|
63
63
|
python -m cc_node.examples.use_node
|
|
64
64
|
python -m cc_node.examples.bench_wire
|
|
65
|
+
python -m cc_node.benchmarks.multi_domain # N children, thread-fanned
|
|
65
66
|
```
|
|
66
67
|
|
|
67
68
|
## Measured (separate-process wire)
|
|
@@ -186,7 +187,9 @@ JS Promise you must await.
|
|
|
186
187
|
**Wire cost vs tiny work.** Round trip is ~100µs class; a one-line JS
|
|
187
188
|
helper on three numbers loses to pure Python. Prefer Python (or a native
|
|
188
189
|
CC module) for small/hot work; use the bridge when Node/npm owns the
|
|
189
|
-
kernel (crypto, parsers, large buffers via shm).
|
|
190
|
+
kernel (crypto, parsers, large buffers via shm). Multi-core: fan across
|
|
191
|
+
`create()` handles from threads —
|
|
192
|
+
`python -m cc_node.benchmarks.multi_domain` (~2.8× on 3 domains here).
|
|
190
193
|
|
|
191
194
|
**Crash isolation, not a sandbox.** The child inherits your environment
|
|
192
195
|
and privileges — do not evaluate untrusted JavaScript. `destroy()` is
|
|
@@ -214,16 +217,37 @@ speaks, from CC.
|
|
|
214
217
|
|
|
215
218
|
## Publishing
|
|
216
219
|
|
|
217
|
-
|
|
220
|
+
**Preferred — PyPI Trusted Publishing (OIDC) from CI** (no API token):
|
|
221
|
+
|
|
222
|
+
1. One-time on
|
|
223
|
+
[Publishing settings](https://pypi.org/manage/project/concurrent-c-node/settings/publishing/):
|
|
224
|
+
- Owner `sreekotay`, repository `concurrent-c`
|
|
225
|
+
- Workflow name `publish-cc-node.yml`
|
|
226
|
+
- Environment name `pypi`
|
|
227
|
+
2. Create a GitHub Environment named `pypi` (optional reviewers encouraged).
|
|
228
|
+
3. Bump `version` in `pyproject.toml`, commit + push, then:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
gh workflow run publish-cc-node.yml
|
|
232
|
+
# or: git tag cc-node-vX.Y.Z && git push --tags
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Local pack / npm sibling (PyPI defaults to CI OIDC after npm):
|
|
218
236
|
|
|
219
237
|
```
|
|
220
|
-
./scripts/publish_bridges.sh
|
|
221
|
-
|
|
238
|
+
./scripts/publish_bridges.sh --publish --minor
|
|
239
|
+
# npm is live; then commit+push bumps and:
|
|
240
|
+
gh workflow run publish-cc-node.yml
|
|
241
|
+
|
|
242
|
+
# local twine fallback:
|
|
243
|
+
./scripts/publish_bridges.sh --publish --minor --pypi-twine
|
|
222
244
|
```
|
|
223
245
|
|
|
224
246
|
A worked tour (builtin Node modules, chains, callbacks, thenables,
|
|
225
247
|
buffers — no npm install needed):
|
|
226
|
-
`python -m cc_node.examples.use_node`.
|
|
248
|
+
`python -m cc_node.examples.use_node`. Wire RTT / shm:
|
|
249
|
+
`python -m cc_node.examples.bench_wire`. Multi-core domains (threads):
|
|
250
|
+
`python -m cc_node.benchmarks.multi_domain`.
|
|
227
251
|
|
|
228
252
|
Adversarial multi-child storm (escaped closures, cooperative
|
|
229
253
|
fanout-destroy, abort inject, handle-leak / RSS soaks):
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "concurrent-c-node"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.15.0"
|
|
8
8
|
description = "JavaScript and npm packages from Python over the Concurrent-C bridge: one spawned Node child per domain, host-controlled lifetime."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -16,8 +16,9 @@ Repository = "https://github.com/sreekotay/concurrent-c"
|
|
|
16
16
|
Documentation = "https://github.com/sreekotay/concurrent-c/blob/main/pypi/cc-node/README.md"
|
|
17
17
|
|
|
18
18
|
[tool.setuptools]
|
|
19
|
-
packages = ["cc_node", "cc_node.examples"]
|
|
19
|
+
packages = ["cc_node", "cc_node.examples", "cc_node.benchmarks"]
|
|
20
20
|
|
|
21
21
|
[tool.setuptools.package-data]
|
|
22
22
|
cc_node = ["broker.cjs"]
|
|
23
23
|
"cc_node.examples" = ["*.py"]
|
|
24
|
+
"cc_node.benchmarks" = ["*.py"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{concurrent_c_node-0.14.0 → concurrent_c_node-0.15.0}/concurrent_c_node.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|