tigrbl-kernel 0.4.2.dev4__tar.gz → 0.4.3__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.
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/PKG-INFO +74 -5
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/README.md +73 -4
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/pyproject.toml +1 -1
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/__init__.py +1 -19
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/_build.py +1 -1
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/_compile.py +100 -1
- tigrbl_kernel-0.4.3/tigrbl_kernel/channel_taxonomy.py +142 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/cross_transport.py +167 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/dispatch_taxonomy.py +47 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/events.py +16 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/helpers.py +2 -2
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/loop_modes.py +19 -1
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/measure.py +1 -1
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/ordering.py +1 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/packed_access.py +131 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/packed_selectors.py +239 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/protocol_anchors.py +49 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_bindings.py +26 -7
- tigrbl_kernel-0.4.3/tigrbl_kernel/protocol_chains/http_stream.py +71 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/protocol_streams.py +470 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/resume_policy.py +78 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/runtime_contracts.py +254 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/rust_compile.py +24 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/rust_plan.py +20 -0
- tigrbl_kernel-0.4.3/tigrbl_kernel/rust_spec.py +36 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/transport_events.py +5 -2
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/types.py +1 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/webtransport_events.py +65 -3
- tigrbl_kernel-0.4.2.dev4/tigrbl_kernel/events.py +0 -6
- tigrbl_kernel-0.4.2.dev4/tigrbl_kernel/protocol_chains/http_stream.py +0 -38
- tigrbl_kernel-0.4.2.dev4/tigrbl_kernel/rust_compile.py +0 -40
- tigrbl_kernel-0.4.2.dev4/tigrbl_kernel/rust_plan.py +0 -14
- tigrbl_kernel-0.4.2.dev4/tigrbl_kernel/rust_spec.py +0 -419
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/LICENSE +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/NOTICE +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/atoms.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/cache.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/callbacks.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/contract_classification.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/core.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/eventkey.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/eventkey_hooks.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/hook_types.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/labels.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/lifecycle_matrix.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/loop_regions.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/models.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/opchannel_capabilities.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/opview_compiler.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/payload.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_chains/__init__.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_chains/http_unary.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_chains/lifespan.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_chains/sse.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_chains/static_files.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_chains/websocket.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_completion.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_fusion.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_legality_matrix.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/protocol_phase_tree.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/segment_fusion.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/subevent_handlers.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/subevent_taxonomy.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/trace.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/transaction_units.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/transport_atoms.py +0 -0
- {tigrbl_kernel-0.4.2.dev4 → tigrbl_kernel-0.4.3}/tigrbl_kernel/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tigrbl-kernel
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: Kernel orchestration for composing Tigrbl runtime plans, bindings, operation dispatch, and optimized ASGI execution.
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -244,7 +244,7 @@ Description-Content-Type: text/markdown
|
|
|
244
244
|
<a href="https://discord.gg/K4YTAPapjR"><img src="https://img.shields.io/badge/Discord-Join%20chat-5865F2?logo=discord&logoColor=white" alt="Discord community for tigrbl-kernel"/></a>
|
|
245
245
|
<a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_kernel/README.md"><img src="https://hits.sh/github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_kernel/README.md.svg?label=hits" alt="Repository hits for tigrbl-kernel README"/></a>
|
|
246
246
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-525252" alt="Apache 2.0 license"/></a>
|
|
247
|
-
<a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%
|
|
247
|
+
<a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%2C%203.11%2C%203.12%2C%203.13%2C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-kernel"/></a>
|
|
248
248
|
<a href="https://github.com/tigrbl/tigrbl/blob/master/docs/README.md"><img src="https://img.shields.io/badge/workspace-core-1f6feb" alt="Workspace group for tigrbl-kernel"/></a>
|
|
249
249
|
</div>
|
|
250
250
|
|
|
@@ -301,7 +301,7 @@ pip install tigrbl-kernel
|
|
|
301
301
|
| Entry points | none declared |
|
|
302
302
|
| Optional extras | none declared |
|
|
303
303
|
| Legal files | `LICENSE`, `NOTICE` |
|
|
304
|
-
| Supported Python | `3.10
|
|
304
|
+
| Supported Python | `3.10, 3.11, 3.12, 3.13, 3.14` |
|
|
305
305
|
|
|
306
306
|
## What It Owns
|
|
307
307
|
|
|
@@ -310,13 +310,80 @@ pip install tigrbl-kernel
|
|
|
310
310
|
Implementation orientation:
|
|
311
311
|
- `tigrbl_kernel`: _build, _compile, atoms, cache, callbacks, contract_classification, core, eventkey, eventkey_hooks, events, helpers, hook_types
|
|
312
312
|
|
|
313
|
+
Package catalog:
|
|
314
|
+
- `tigrbl_kernel/core.py`, `tigrbl_kernel/_build.py`, `tigrbl_kernel/_compile.py`, `tigrbl_kernel/models.py`, `tigrbl_kernel/types.py`, and `tigrbl_kernel/payload.py`: kernel objects, operation views, packed plans, build/compile helpers, and payload contracts.
|
|
315
|
+
- `tigrbl_kernel/ordering.py`, `tigrbl_kernel/labels.py`, `tigrbl_kernel/hook_types.py`, `tigrbl_kernel/callbacks.py`, and `tigrbl_kernel/eventkey_hooks.py`: hook ordering, diagnostic labels, callback shape, and event-key-aware hook plumbing.
|
|
316
|
+
- `tigrbl_kernel/cache.py`, `tigrbl_kernel/trace.py`, and `tigrbl_kernel/measure.py`: cached plans, execution trace support, and measurement views.
|
|
317
|
+
- `tigrbl_kernel/atoms.py`, `tigrbl_kernel/transport_atoms.py`, and `tigrbl_kernel/transaction_units.py`: atom references and transaction/transport plan units.
|
|
318
|
+
- `tigrbl_kernel/protocol_bindings.py`, `tigrbl_kernel/protocol_phase_tree.py`, `tigrbl_kernel/protocol_chains/`, `tigrbl_kernel/protocol_completion.py`, `tigrbl_kernel/protocol_fusion.py`, and `tigrbl_kernel/protocol_legality_matrix.py`: transport-specific plan compilation, phase tree construction, chain definitions, completion semantics, fusion, and legality checks.
|
|
319
|
+
- `tigrbl_kernel/eventkey.py`, `tigrbl_kernel/events.py`, `tigrbl_kernel/transport_events.py`, `tigrbl_kernel/webtransport_events.py`, `tigrbl_kernel/subevent_taxonomy.py`, and `tigrbl_kernel/subevent_handlers.py`: event-key construction, subevent taxonomy, and protocol subevent handler mapping.
|
|
320
|
+
- `tigrbl_kernel/opchannel_capabilities.py`, `tigrbl_kernel/loop_modes.py`, `tigrbl_kernel/loop_regions.py`, `tigrbl_kernel/segment_fusion.py`, and `tigrbl_kernel/contract_classification.py`: channel capability checks, loop planning, segment grouping, and contract classification.
|
|
321
|
+
- `tigrbl_kernel/rust_plan.py`, `tigrbl_kernel/rust_compile.py`, and `tigrbl_kernel/rust_spec.py`: deprecated compatibility shims; kernel planning is Python-only.
|
|
322
|
+
|
|
313
323
|
## Public API and Import Surface
|
|
314
324
|
|
|
315
325
|
- Import roots: `tigrbl_kernel`.
|
|
316
|
-
- Public symbols: `BatchOpPlan`, `
|
|
326
|
+
- Public symbols: `BatchOpPlan`, `Kernel`, `OpView`, `PackedKernel`, `SchemaIn`, `SchemaOut`, `build_kernel_plan`, `build_packed_kernel`, `build_packed_kernel_measurement_view`.
|
|
317
327
|
- Workspace dependencies: [`tigrbl-typing`](https://pypi.org/project/tigrbl-typing/), [`tigrbl-atoms`](https://pypi.org/project/tigrbl-atoms/), [`tigrbl-core`](https://pypi.org/project/tigrbl-core/).
|
|
318
328
|
- External runtime dependencies: none declared.
|
|
319
329
|
|
|
330
|
+
## Kernel Semantics
|
|
331
|
+
|
|
332
|
+
The kernel turns specs, operation inventories, hooks, atoms, and protocol bindings into executable plans. It does not own app authoring syntax, persistence engines, or concrete ASGI classes. Its job is to compile the behavior that runtime-owned routing will execute.
|
|
333
|
+
|
|
334
|
+
The basic flow is:
|
|
335
|
+
|
|
336
|
+
```text
|
|
337
|
+
specs + model metadata + bindings + hooks
|
|
338
|
+
-> operation views
|
|
339
|
+
-> ordered phase plan
|
|
340
|
+
-> packed kernel
|
|
341
|
+
-> runtime execution and diagnostics
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
`Kernel` and `PackedKernel` are the planning surfaces; `OpView` is the operation-level view of schemas, handlers, hooks, bindings, and labels. `build_kernel_plan(...)` and `build_packed_kernel(...)` are useful for tests and framework packages that need to verify the compiled plan without driving a full ASGI request.
|
|
345
|
+
|
|
346
|
+
## Protocol Planning
|
|
347
|
+
|
|
348
|
+
Protocol planning keeps binding kind, family, framing, exchange, lane, subevent rows, and atom anchors separate. The current planner handles:
|
|
349
|
+
|
|
350
|
+
| Binding kind | Runtime family | Default framing | Plan shape |
|
|
351
|
+
|---|---|---|---|
|
|
352
|
+
| `http.rest` / `https.rest` | request | JSON | request received, handler invoke, response emit. |
|
|
353
|
+
| `http.jsonrpc` / `https.jsonrpc` | request | JSON-RPC | framing decode, dispatch, handler invoke, framing encode. |
|
|
354
|
+
| `http.stream` / `https.stream` | stream | stream | handler invoke, transport emit, stream close. |
|
|
355
|
+
| `http.sse` / `https.sse` | stream | SSE | encode event, emit event, close stream. |
|
|
356
|
+
| `ws` / `wss` / `websocket` | message | text or negotiated JSON-RPC | accept, decode, dispatch, handler, emit/close. |
|
|
357
|
+
| `webtransport` | session, stream, or datagram | WebTransport outer framing | lane-specific session, stream, or datagram rows with inner-framing validation. |
|
|
358
|
+
|
|
359
|
+
Unsupported or ambiguous bindings raise planning errors. For example, WebSocket bindings do not accept HTTP methods, HTTP JSON-RPC requires an RPC method, WebTransport request/response exchange is unsupported, and WebTransport outer framing must remain `webtransport`.
|
|
360
|
+
|
|
361
|
+
## Hook Ordering and Labels
|
|
362
|
+
|
|
363
|
+
The kernel orders security dependencies, dependencies, system hooks, user hooks, atoms, and handlers into phase plans. Labels are part of the diagnostics contract:
|
|
364
|
+
|
|
365
|
+
```text
|
|
366
|
+
PRE_HANDLER:secdep:myapp.auth.require_user
|
|
367
|
+
PRE_HANDLER:dep:myapp.context.load_tenant
|
|
368
|
+
HANDLER:hook:sys:handler:create@HANDLER
|
|
369
|
+
EGRESS_SHAPE:atom:wire:dump
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Use labels to debug and test ordering. Do not use them as application APIs; use specs, decorators, dependencies, and hooks for configuration.
|
|
373
|
+
|
|
374
|
+
## Diagnostics and Traceability
|
|
375
|
+
|
|
376
|
+
Kernel plans feed `/system/kernelz` in concrete applications. Trace and measurement helpers make it possible to assert plan shape, count phase work, and inspect compiled execution without relying on a live server. This is especially important for transport work, where a route can look correct while the protocol chain is missing required event rows or capability masks.
|
|
377
|
+
|
|
378
|
+
## Best Practices
|
|
379
|
+
|
|
380
|
+
- Compile plans from explicit specs and bindings; do not guess transport behavior from URL strings alone.
|
|
381
|
+
- Keep protocol support checks fail-closed and close to planning.
|
|
382
|
+
- Preserve separate event rows for request, stream, message, session, and datagram families.
|
|
383
|
+
- Add tests at the kernel layer when changing hook order, labels, phase rows, protocol legality, or capability masks.
|
|
384
|
+
- Use measurement views for plan review instead of parsing private object internals.
|
|
385
|
+
- Keep runtime side effects out of kernel code; the kernel should plan, classify, and label, not perform IO.
|
|
386
|
+
|
|
320
387
|
## Usage Examples
|
|
321
388
|
|
|
322
389
|
### Verify the installed package
|
|
@@ -376,6 +443,8 @@ Choose `tigrbl-kernel` when the quick-answer table matches your use case. Choose
|
|
|
376
443
|
- [Package layout](https://github.com/tigrbl/tigrbl/blob/master/docs/developer/PACKAGE_LAYOUT.md)
|
|
377
444
|
- [Current target](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_TARGET.md)
|
|
378
445
|
- [Current state](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_STATE.md)
|
|
446
|
+
- [Next steps](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/NEXT_STEPS.md)
|
|
447
|
+
- [Documentation pointers](https://github.com/tigrbl/tigrbl/blob/master/docs/governance/DOC_POINTERS.md)
|
|
379
448
|
- [SSOT registry](https://github.com/tigrbl/tigrbl/blob/master/.ssot/registry.json)
|
|
380
449
|
- [Release workflow](https://github.com/tigrbl/tigrbl/actions/workflows/publish.yml)
|
|
381
450
|
|
|
@@ -387,7 +456,7 @@ Choose `tigrbl-kernel` when the quick-answer table matches your use case. Choose
|
|
|
387
456
|
|
|
388
457
|
## Package-local Boundary
|
|
389
458
|
|
|
390
|
-
This README is the package-local distribution entry point for `tigrbl-kernel`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
|
|
459
|
+
This file is a package-local distribution entry point. This README is the package-local distribution entry point for `tigrbl-kernel`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
|
|
391
460
|
|
|
392
461
|
## License
|
|
393
462
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<a href="https://discord.gg/K4YTAPapjR"><img src="https://img.shields.io/badge/Discord-Join%20chat-5865F2?logo=discord&logoColor=white" alt="Discord community for tigrbl-kernel"/></a>
|
|
8
8
|
<a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_kernel/README.md"><img src="https://hits.sh/github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_kernel/README.md.svg?label=hits" alt="Repository hits for tigrbl-kernel README"/></a>
|
|
9
9
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-525252" alt="Apache 2.0 license"/></a>
|
|
10
|
-
<a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%
|
|
10
|
+
<a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%2C%203.11%2C%203.12%2C%203.13%2C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-kernel"/></a>
|
|
11
11
|
<a href="https://github.com/tigrbl/tigrbl/blob/master/docs/README.md"><img src="https://img.shields.io/badge/workspace-core-1f6feb" alt="Workspace group for tigrbl-kernel"/></a>
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -64,7 +64,7 @@ pip install tigrbl-kernel
|
|
|
64
64
|
| Entry points | none declared |
|
|
65
65
|
| Optional extras | none declared |
|
|
66
66
|
| Legal files | `LICENSE`, `NOTICE` |
|
|
67
|
-
| Supported Python | `3.10
|
|
67
|
+
| Supported Python | `3.10, 3.11, 3.12, 3.13, 3.14` |
|
|
68
68
|
|
|
69
69
|
## What It Owns
|
|
70
70
|
|
|
@@ -73,13 +73,80 @@ pip install tigrbl-kernel
|
|
|
73
73
|
Implementation orientation:
|
|
74
74
|
- `tigrbl_kernel`: _build, _compile, atoms, cache, callbacks, contract_classification, core, eventkey, eventkey_hooks, events, helpers, hook_types
|
|
75
75
|
|
|
76
|
+
Package catalog:
|
|
77
|
+
- `tigrbl_kernel/core.py`, `tigrbl_kernel/_build.py`, `tigrbl_kernel/_compile.py`, `tigrbl_kernel/models.py`, `tigrbl_kernel/types.py`, and `tigrbl_kernel/payload.py`: kernel objects, operation views, packed plans, build/compile helpers, and payload contracts.
|
|
78
|
+
- `tigrbl_kernel/ordering.py`, `tigrbl_kernel/labels.py`, `tigrbl_kernel/hook_types.py`, `tigrbl_kernel/callbacks.py`, and `tigrbl_kernel/eventkey_hooks.py`: hook ordering, diagnostic labels, callback shape, and event-key-aware hook plumbing.
|
|
79
|
+
- `tigrbl_kernel/cache.py`, `tigrbl_kernel/trace.py`, and `tigrbl_kernel/measure.py`: cached plans, execution trace support, and measurement views.
|
|
80
|
+
- `tigrbl_kernel/atoms.py`, `tigrbl_kernel/transport_atoms.py`, and `tigrbl_kernel/transaction_units.py`: atom references and transaction/transport plan units.
|
|
81
|
+
- `tigrbl_kernel/protocol_bindings.py`, `tigrbl_kernel/protocol_phase_tree.py`, `tigrbl_kernel/protocol_chains/`, `tigrbl_kernel/protocol_completion.py`, `tigrbl_kernel/protocol_fusion.py`, and `tigrbl_kernel/protocol_legality_matrix.py`: transport-specific plan compilation, phase tree construction, chain definitions, completion semantics, fusion, and legality checks.
|
|
82
|
+
- `tigrbl_kernel/eventkey.py`, `tigrbl_kernel/events.py`, `tigrbl_kernel/transport_events.py`, `tigrbl_kernel/webtransport_events.py`, `tigrbl_kernel/subevent_taxonomy.py`, and `tigrbl_kernel/subevent_handlers.py`: event-key construction, subevent taxonomy, and protocol subevent handler mapping.
|
|
83
|
+
- `tigrbl_kernel/opchannel_capabilities.py`, `tigrbl_kernel/loop_modes.py`, `tigrbl_kernel/loop_regions.py`, `tigrbl_kernel/segment_fusion.py`, and `tigrbl_kernel/contract_classification.py`: channel capability checks, loop planning, segment grouping, and contract classification.
|
|
84
|
+
- `tigrbl_kernel/rust_plan.py`, `tigrbl_kernel/rust_compile.py`, and `tigrbl_kernel/rust_spec.py`: deprecated compatibility shims; kernel planning is Python-only.
|
|
85
|
+
|
|
76
86
|
## Public API and Import Surface
|
|
77
87
|
|
|
78
88
|
- Import roots: `tigrbl_kernel`.
|
|
79
|
-
- Public symbols: `BatchOpPlan`, `
|
|
89
|
+
- Public symbols: `BatchOpPlan`, `Kernel`, `OpView`, `PackedKernel`, `SchemaIn`, `SchemaOut`, `build_kernel_plan`, `build_packed_kernel`, `build_packed_kernel_measurement_view`.
|
|
80
90
|
- Workspace dependencies: [`tigrbl-typing`](https://pypi.org/project/tigrbl-typing/), [`tigrbl-atoms`](https://pypi.org/project/tigrbl-atoms/), [`tigrbl-core`](https://pypi.org/project/tigrbl-core/).
|
|
81
91
|
- External runtime dependencies: none declared.
|
|
82
92
|
|
|
93
|
+
## Kernel Semantics
|
|
94
|
+
|
|
95
|
+
The kernel turns specs, operation inventories, hooks, atoms, and protocol bindings into executable plans. It does not own app authoring syntax, persistence engines, or concrete ASGI classes. Its job is to compile the behavior that runtime-owned routing will execute.
|
|
96
|
+
|
|
97
|
+
The basic flow is:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
specs + model metadata + bindings + hooks
|
|
101
|
+
-> operation views
|
|
102
|
+
-> ordered phase plan
|
|
103
|
+
-> packed kernel
|
|
104
|
+
-> runtime execution and diagnostics
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`Kernel` and `PackedKernel` are the planning surfaces; `OpView` is the operation-level view of schemas, handlers, hooks, bindings, and labels. `build_kernel_plan(...)` and `build_packed_kernel(...)` are useful for tests and framework packages that need to verify the compiled plan without driving a full ASGI request.
|
|
108
|
+
|
|
109
|
+
## Protocol Planning
|
|
110
|
+
|
|
111
|
+
Protocol planning keeps binding kind, family, framing, exchange, lane, subevent rows, and atom anchors separate. The current planner handles:
|
|
112
|
+
|
|
113
|
+
| Binding kind | Runtime family | Default framing | Plan shape |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| `http.rest` / `https.rest` | request | JSON | request received, handler invoke, response emit. |
|
|
116
|
+
| `http.jsonrpc` / `https.jsonrpc` | request | JSON-RPC | framing decode, dispatch, handler invoke, framing encode. |
|
|
117
|
+
| `http.stream` / `https.stream` | stream | stream | handler invoke, transport emit, stream close. |
|
|
118
|
+
| `http.sse` / `https.sse` | stream | SSE | encode event, emit event, close stream. |
|
|
119
|
+
| `ws` / `wss` / `websocket` | message | text or negotiated JSON-RPC | accept, decode, dispatch, handler, emit/close. |
|
|
120
|
+
| `webtransport` | session, stream, or datagram | WebTransport outer framing | lane-specific session, stream, or datagram rows with inner-framing validation. |
|
|
121
|
+
|
|
122
|
+
Unsupported or ambiguous bindings raise planning errors. For example, WebSocket bindings do not accept HTTP methods, HTTP JSON-RPC requires an RPC method, WebTransport request/response exchange is unsupported, and WebTransport outer framing must remain `webtransport`.
|
|
123
|
+
|
|
124
|
+
## Hook Ordering and Labels
|
|
125
|
+
|
|
126
|
+
The kernel orders security dependencies, dependencies, system hooks, user hooks, atoms, and handlers into phase plans. Labels are part of the diagnostics contract:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
PRE_HANDLER:secdep:myapp.auth.require_user
|
|
130
|
+
PRE_HANDLER:dep:myapp.context.load_tenant
|
|
131
|
+
HANDLER:hook:sys:handler:create@HANDLER
|
|
132
|
+
EGRESS_SHAPE:atom:wire:dump
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Use labels to debug and test ordering. Do not use them as application APIs; use specs, decorators, dependencies, and hooks for configuration.
|
|
136
|
+
|
|
137
|
+
## Diagnostics and Traceability
|
|
138
|
+
|
|
139
|
+
Kernel plans feed `/system/kernelz` in concrete applications. Trace and measurement helpers make it possible to assert plan shape, count phase work, and inspect compiled execution without relying on a live server. This is especially important for transport work, where a route can look correct while the protocol chain is missing required event rows or capability masks.
|
|
140
|
+
|
|
141
|
+
## Best Practices
|
|
142
|
+
|
|
143
|
+
- Compile plans from explicit specs and bindings; do not guess transport behavior from URL strings alone.
|
|
144
|
+
- Keep protocol support checks fail-closed and close to planning.
|
|
145
|
+
- Preserve separate event rows for request, stream, message, session, and datagram families.
|
|
146
|
+
- Add tests at the kernel layer when changing hook order, labels, phase rows, protocol legality, or capability masks.
|
|
147
|
+
- Use measurement views for plan review instead of parsing private object internals.
|
|
148
|
+
- Keep runtime side effects out of kernel code; the kernel should plan, classify, and label, not perform IO.
|
|
149
|
+
|
|
83
150
|
## Usage Examples
|
|
84
151
|
|
|
85
152
|
### Verify the installed package
|
|
@@ -139,6 +206,8 @@ Choose `tigrbl-kernel` when the quick-answer table matches your use case. Choose
|
|
|
139
206
|
- [Package layout](https://github.com/tigrbl/tigrbl/blob/master/docs/developer/PACKAGE_LAYOUT.md)
|
|
140
207
|
- [Current target](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_TARGET.md)
|
|
141
208
|
- [Current state](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_STATE.md)
|
|
209
|
+
- [Next steps](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/NEXT_STEPS.md)
|
|
210
|
+
- [Documentation pointers](https://github.com/tigrbl/tigrbl/blob/master/docs/governance/DOC_POINTERS.md)
|
|
142
211
|
- [SSOT registry](https://github.com/tigrbl/tigrbl/blob/master/.ssot/registry.json)
|
|
143
212
|
- [Release workflow](https://github.com/tigrbl/tigrbl/actions/workflows/publish.yml)
|
|
144
213
|
|
|
@@ -150,7 +219,7 @@ Choose `tigrbl-kernel` when the quick-answer table matches your use case. Choose
|
|
|
150
219
|
|
|
151
220
|
## Package-local Boundary
|
|
152
221
|
|
|
153
|
-
This README is the package-local distribution entry point for `tigrbl-kernel`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
|
|
222
|
+
This file is a package-local distribution entry point. This README is the package-local distribution entry point for `tigrbl-kernel`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
|
|
154
223
|
|
|
155
224
|
## License
|
|
156
225
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tigrbl-kernel"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.3"
|
|
4
4
|
description = "Kernel orchestration for composing Tigrbl runtime plans, bindings, operation dispatch, and optimized ASGI execution."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { file = "LICENSE" }
|
|
@@ -3,19 +3,6 @@ from __future__ import annotations
|
|
|
3
3
|
from importlib import import_module
|
|
4
4
|
from typing import Any, Dict, List, Mapping
|
|
5
5
|
|
|
6
|
-
try: # pragma: no cover - additive optional integration
|
|
7
|
-
_runtime_rust = import_module("tigrbl_runtime.rust")
|
|
8
|
-
ExecutionBackend = _runtime_rust.ExecutionBackend
|
|
9
|
-
RustBackendConfig = _runtime_rust.RustBackendConfig
|
|
10
|
-
except Exception: # pragma: no cover
|
|
11
|
-
ExecutionBackend = RustBackendConfig = None
|
|
12
|
-
|
|
13
|
-
from .rust_compile import (
|
|
14
|
-
build_rust_kernel,
|
|
15
|
-
build_rust_parity_snapshot,
|
|
16
|
-
normalize_rust_spec,
|
|
17
|
-
)
|
|
18
|
-
from .rust_plan import RustPlan
|
|
19
6
|
from .measure import (
|
|
20
7
|
build_packed_kernel_measurement_view,
|
|
21
8
|
load_packed_kernel_hot_block,
|
|
@@ -80,18 +67,13 @@ def plan_labels(model: type, alias: str) -> list[str]:
|
|
|
80
67
|
|
|
81
68
|
|
|
82
69
|
__all__ = [
|
|
83
|
-
"ExecutionBackend",
|
|
84
70
|
"Kernel",
|
|
85
|
-
"RustBackendConfig",
|
|
86
|
-
"RustPlan",
|
|
87
71
|
"BatchOpPlan",
|
|
88
72
|
"OpView",
|
|
89
73
|
"PackedKernel",
|
|
90
74
|
"SchemaIn",
|
|
91
75
|
"SchemaOut",
|
|
92
76
|
"build_kernel_plan",
|
|
93
|
-
"build_rust_kernel",
|
|
94
|
-
"build_rust_parity_snapshot",
|
|
95
77
|
"build_packed_kernel",
|
|
96
78
|
"build_packed_kernel_measurement_view",
|
|
97
79
|
"get_cached_specs",
|
|
@@ -99,9 +81,9 @@ __all__ = [
|
|
|
99
81
|
"load_packed_kernel_hot_block",
|
|
100
82
|
"load_packed_kernel_hot_sections",
|
|
101
83
|
"measure_packed_kernel",
|
|
102
|
-
"normalize_rust_spec",
|
|
103
84
|
"packed_kernel_measurement",
|
|
104
85
|
"plan_labels",
|
|
86
|
+
"protocol_streams",
|
|
105
87
|
"serialize_packed_kernel_measurement_view",
|
|
106
88
|
"segment_fusion",
|
|
107
89
|
"transport_atoms",
|
|
@@ -15,7 +15,7 @@ from tigrbl_atoms.atoms.sys.phase_db import run as _bind_phase_db
|
|
|
15
15
|
from tigrbl_atoms.phases import phase_info
|
|
16
16
|
from tigrbl_atoms.types import EdgeTarget, PhaseTreeEdge, PhaseTreeNode, error_phase_for
|
|
17
17
|
from tigrbl_core.config.resolver import resolve_cfg
|
|
18
|
-
from tigrbl_typing.phases import normalize_phase
|
|
18
|
+
from tigrbl_typing.phases import canonicalize_phase_input as normalize_phase
|
|
19
19
|
|
|
20
20
|
from . import events as _ev
|
|
21
21
|
from .atoms import (
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import replace
|
|
4
|
+
from types import SimpleNamespace
|
|
4
5
|
from typing import Any, Mapping
|
|
5
6
|
|
|
6
7
|
from tigrbl_atoms import StepFn
|
|
8
|
+
from tigrbl_core._spec.binding_spec import HttpRestBindingSpec
|
|
7
9
|
from tigrbl_core.config.constants import __JSONRPC_DEFAULT_ENDPOINT__
|
|
10
|
+
from tigrbl_core._spec.op_spec import OpSpec
|
|
11
|
+
from tigrbl_core._spec.well_known_spec import well_known_op_alias
|
|
8
12
|
|
|
9
13
|
from . import events as _ev
|
|
10
14
|
from .models import KernelPlan, OpKey, OpMeta, OpView
|
|
@@ -24,6 +28,101 @@ from .utils import (
|
|
|
24
28
|
DEFAULT_PHASE_ORDER = tuple(getattr(_ev, "PHASES", ())) or _DEFAULT_PHASE_ORDER
|
|
25
29
|
|
|
26
30
|
|
|
31
|
+
def _pathspec_iter(app: Any) -> tuple[Any, ...]:
|
|
32
|
+
collected: list[Any] = []
|
|
33
|
+
collected.extend(tuple(getattr(app, "_tigrbl_path_specs", ()) or ()))
|
|
34
|
+
routers = getattr(app, "routers", None)
|
|
35
|
+
if isinstance(routers, Mapping):
|
|
36
|
+
router_values = tuple(routers.values())
|
|
37
|
+
elif isinstance(routers, (list, tuple)):
|
|
38
|
+
router_values = tuple(routers)
|
|
39
|
+
else:
|
|
40
|
+
router_values = ()
|
|
41
|
+
for router in router_values:
|
|
42
|
+
collected.extend(tuple(getattr(router, "_tigrbl_path_specs", ()) or ()))
|
|
43
|
+
|
|
44
|
+
seen: set[tuple[str, str, str]] = set()
|
|
45
|
+
deduped: list[Any] = []
|
|
46
|
+
for path in collected:
|
|
47
|
+
resource = getattr(path, "well_known", None)
|
|
48
|
+
key = (
|
|
49
|
+
str(getattr(path, "kind", "")),
|
|
50
|
+
str(getattr(path, "path", "")),
|
|
51
|
+
str(getattr(resource, "name", "")),
|
|
52
|
+
)
|
|
53
|
+
if key in seen:
|
|
54
|
+
continue
|
|
55
|
+
seen.add(key)
|
|
56
|
+
deduped.append(path)
|
|
57
|
+
return tuple(deduped)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _well_known_path_model(app: Any) -> type | None:
|
|
61
|
+
pathspecs = tuple(
|
|
62
|
+
path
|
|
63
|
+
for path in _pathspec_iter(app)
|
|
64
|
+
if getattr(path, "kind", None) == "well-known"
|
|
65
|
+
and getattr(path, "well_known", None) is not None
|
|
66
|
+
)
|
|
67
|
+
if not pathspecs:
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
ops: list[Any] = []
|
|
71
|
+
resources: dict[str, dict[str, Any]] = {}
|
|
72
|
+
for path in pathspecs:
|
|
73
|
+
resource = path.well_known
|
|
74
|
+
alias = well_known_op_alias(resource.name)
|
|
75
|
+
resources[alias] = {
|
|
76
|
+
"name": resource.name,
|
|
77
|
+
"payload": resource.payload,
|
|
78
|
+
"media_type": resource.media_type,
|
|
79
|
+
"status_code": resource.status_code,
|
|
80
|
+
"headers": dict(resource.headers or {}),
|
|
81
|
+
}
|
|
82
|
+
ops.append(
|
|
83
|
+
OpSpec(
|
|
84
|
+
alias=alias,
|
|
85
|
+
target="well_known",
|
|
86
|
+
arity="collection",
|
|
87
|
+
persist="skip",
|
|
88
|
+
expose_routes=False,
|
|
89
|
+
expose_rpc=False,
|
|
90
|
+
bindings=(
|
|
91
|
+
HttpRestBindingSpec(
|
|
92
|
+
proto="http.rest",
|
|
93
|
+
path=str(path.path),
|
|
94
|
+
methods=("GET",),
|
|
95
|
+
),
|
|
96
|
+
),
|
|
97
|
+
status_code=resource.status_code,
|
|
98
|
+
exchange="request_response",
|
|
99
|
+
tx_scope="none",
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
ops_tuple = tuple(ops)
|
|
104
|
+
model = type("TigrblWellKnownPathOps", (), {})
|
|
105
|
+
model.resource_name = "well_known"
|
|
106
|
+
model.__tigrbl_well_known_resources__ = resources
|
|
107
|
+
model.__tigrbl_ops__ = ops_tuple
|
|
108
|
+
model.ops = SimpleNamespace(
|
|
109
|
+
all=ops_tuple,
|
|
110
|
+
by_alias={op.alias: (op,) for op in ops_tuple},
|
|
111
|
+
by_key={(op.alias, op.target): op for op in ops_tuple},
|
|
112
|
+
)
|
|
113
|
+
model.opspecs = model.ops
|
|
114
|
+
setattr(app, "_tigrbl_kernel_well_known_model", model)
|
|
115
|
+
return model
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _compile_models(app: Any) -> tuple[Any, ...]:
|
|
119
|
+
models = list(_table_iter(app))
|
|
120
|
+
well_known_model = _well_known_path_model(app)
|
|
121
|
+
if well_known_model is not None:
|
|
122
|
+
models.append(well_known_model)
|
|
123
|
+
return tuple(models)
|
|
124
|
+
|
|
125
|
+
|
|
27
126
|
def _compile_opview_from_specs(self: Any, specs: Mapping[str, Any], sp: Any) -> OpView:
|
|
28
127
|
return compile_opview_from_specs(specs, sp)
|
|
29
128
|
|
|
@@ -50,7 +149,7 @@ def _compile_plan(self: Any, app: Any) -> KernelPlan:
|
|
|
50
149
|
egress_chain = self._build_egress(app)
|
|
51
150
|
phases, mainline_phases, error_phases = _phase_info_map(DEFAULT_PHASE_ORDER)
|
|
52
151
|
|
|
53
|
-
for model in
|
|
152
|
+
for model in _compile_models(app):
|
|
54
153
|
for sp in _opspecs(model):
|
|
55
154
|
meta_index = len(opmeta)
|
|
56
155
|
target = (getattr(sp, "target", sp.alias) or sp.alias).lower()
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable, Mapping
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from tigrbl_core._spec.hook_spec import matches_hook_selector
|
|
7
|
+
|
|
8
|
+
from .webtransport_events import validate_webtransport_event_payload
|
|
9
|
+
|
|
10
|
+
WEBTRANSPORT_SUBEVENTS = {
|
|
11
|
+
"webtransport.connect": "session.open",
|
|
12
|
+
"webtransport.accept": "session.accept",
|
|
13
|
+
"webtransport.disconnect": "session.close",
|
|
14
|
+
"webtransport.close": "session.close",
|
|
15
|
+
"webtransport.stream.receive": "stream.chunk.received",
|
|
16
|
+
"webtransport.stream.send": "stream.chunk.emit",
|
|
17
|
+
"webtransport.stream.close": "stream.close",
|
|
18
|
+
"webtransport.stream.reset": "stream.close",
|
|
19
|
+
"webtransport.stream.stop_sending": "stream.close",
|
|
20
|
+
"webtransport.datagram.receive": "datagram.received",
|
|
21
|
+
"webtransport.datagram.send": "datagram.emit",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def normalize_exchange(exchange: str | None) -> str:
|
|
26
|
+
token = str(exchange or "request_response")
|
|
27
|
+
if token == "bidirectional":
|
|
28
|
+
return "bidirectional_stream"
|
|
29
|
+
return token
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def channel_family(scope_type: str, exchange: str) -> str:
|
|
33
|
+
exchange = normalize_exchange(exchange)
|
|
34
|
+
if scope_type == "websocket":
|
|
35
|
+
return "socket"
|
|
36
|
+
if scope_type == "webtransport":
|
|
37
|
+
return "session"
|
|
38
|
+
if exchange in {"server_stream", "client_stream", "bidirectional_stream"}:
|
|
39
|
+
return "stream"
|
|
40
|
+
if exchange == "fire_and_forget":
|
|
41
|
+
return "request"
|
|
42
|
+
return "response"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def channel_kind(scope_type: str, exchange: str) -> str:
|
|
46
|
+
exchange = normalize_exchange(exchange)
|
|
47
|
+
if scope_type == "websocket":
|
|
48
|
+
return "websocket"
|
|
49
|
+
if scope_type == "webtransport":
|
|
50
|
+
return "webtransport"
|
|
51
|
+
if exchange in {"server_stream", "client_stream", "bidirectional_stream"}:
|
|
52
|
+
return "stream"
|
|
53
|
+
if exchange == "event_stream":
|
|
54
|
+
return "sse"
|
|
55
|
+
return "http"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def channel_subevents(scope_type: str, exchange: str) -> tuple[str, ...]:
|
|
59
|
+
exchange = normalize_exchange(exchange)
|
|
60
|
+
if scope_type in {"websocket", "webtransport"}:
|
|
61
|
+
return ("connect", "receive", "emit", "complete", "disconnect")
|
|
62
|
+
if exchange in {"server_stream", "client_stream", "bidirectional_stream", "event_stream"}:
|
|
63
|
+
return ("receive", "emit", "complete")
|
|
64
|
+
return ("receive", "emit", "complete")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def webtransport_event_metadata(
|
|
68
|
+
*,
|
|
69
|
+
direction: str,
|
|
70
|
+
message: Mapping[str, Any],
|
|
71
|
+
) -> dict[str, Any]:
|
|
72
|
+
event_type = str(message.get("type") or "")
|
|
73
|
+
metadata: dict[str, Any] = {
|
|
74
|
+
"binding": "webtransport",
|
|
75
|
+
"event_type": event_type,
|
|
76
|
+
"type": event_type,
|
|
77
|
+
"subevent": WEBTRANSPORT_SUBEVENTS.get(event_type, event_type),
|
|
78
|
+
"framing": message.get("framing"),
|
|
79
|
+
}
|
|
80
|
+
try:
|
|
81
|
+
projection = validate_webtransport_event_payload(
|
|
82
|
+
event=event_type,
|
|
83
|
+
channel=direction,
|
|
84
|
+
payload=dict(message),
|
|
85
|
+
)
|
|
86
|
+
except ValueError:
|
|
87
|
+
projection = {}
|
|
88
|
+
for key in (
|
|
89
|
+
"family",
|
|
90
|
+
"lane",
|
|
91
|
+
"exchange",
|
|
92
|
+
"stream_initiator",
|
|
93
|
+
"stream_direction",
|
|
94
|
+
"direction",
|
|
95
|
+
"lane_id",
|
|
96
|
+
"stream_ordinal",
|
|
97
|
+
"stream_id_width",
|
|
98
|
+
):
|
|
99
|
+
if projection.get(key) is not None:
|
|
100
|
+
metadata[key] = projection[key]
|
|
101
|
+
if "family" not in metadata:
|
|
102
|
+
if ".stream." in event_type:
|
|
103
|
+
metadata["family"] = "stream"
|
|
104
|
+
elif ".datagram." in event_type:
|
|
105
|
+
metadata["family"] = "datagram"
|
|
106
|
+
else:
|
|
107
|
+
metadata["family"] = "session"
|
|
108
|
+
if "lane" not in metadata:
|
|
109
|
+
metadata["lane"] = metadata["family"]
|
|
110
|
+
if "exchange" not in metadata:
|
|
111
|
+
metadata["exchange"] = "request_response"
|
|
112
|
+
return metadata
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def select_webtransport_hooks(
|
|
116
|
+
hooks: Iterable[Any],
|
|
117
|
+
*,
|
|
118
|
+
direction: str,
|
|
119
|
+
metadata: Mapping[str, Any],
|
|
120
|
+
) -> tuple[Any, ...]:
|
|
121
|
+
allowed_phases = (
|
|
122
|
+
{"PRE_HANDLER", "HANDLER"}
|
|
123
|
+
if direction == "receive"
|
|
124
|
+
else {"POST_HANDLER", "POST_RESPONSE"}
|
|
125
|
+
)
|
|
126
|
+
return tuple(
|
|
127
|
+
hook
|
|
128
|
+
for hook in hooks
|
|
129
|
+
if str(getattr(hook.phase, "value", hook.phase)) in allowed_phases
|
|
130
|
+
if matches_hook_selector(hook, metadata)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
__all__ = [
|
|
135
|
+
"WEBTRANSPORT_SUBEVENTS",
|
|
136
|
+
"channel_family",
|
|
137
|
+
"channel_kind",
|
|
138
|
+
"channel_subevents",
|
|
139
|
+
"normalize_exchange",
|
|
140
|
+
"select_webtransport_hooks",
|
|
141
|
+
"webtransport_event_metadata",
|
|
142
|
+
]
|