-
Notifications
You must be signed in to change notification settings - Fork 9
Staging
Staging lets structs be accumulated into named staging areas and released into a channel as a
batch, rather than sent one at a time. A staging area is identified by a staging_id and holds a list
of structs that have been staged but not yet released.
Staging is available over REST, from Python, and from inside the csp graph.
Either declare it on the channel:
from typing import Annotated
from csp_gateway.server.gateway.csp.stage import Stage
class MyChannels(GatewayChannels):
orders: Annotated[ts[OrderStruct], Stage()] = Noneor enable it in a module's connect:
channels.set_stage("orders")Both are equivalent, and enabling a channel twice is a no-op. channels.staged_channels() lists the
channels that have staging enabled.
struct and staging_ids combine to select what is affected. The distinction between None (unset)
and [] (empty list) is meaningful for staging_ids.
struct |
staging_ids |
Effect |
|---|---|---|
None |
None or []
|
Open a new empty staging area |
None |
[ids] |
ValueError — nothing to add |
| struct | None |
Add to the most recent staging, or open one if none exist |
| struct | [] |
Add to every staging that does not already hold it; open one if none exist, or if it is already in all of them |
| struct | [ids] |
Add to each named staging; KeyError if an id is unknown |
Returns the list of staging ids affected.
struct |
staging_ids |
Effect |
|---|---|---|
None |
None |
Drop the most recent staging area entirely |
None |
[] |
Drop every staging area |
None |
[ids] |
Empty the named staging areas, leaving them open |
| struct | None |
Remove from the most recent staging holding it |
| struct | [] |
Remove from every staging holding it |
| struct | [ids] |
Remove from each named staging |
Note the asymmetry: with no struct, an unset staging_ids drops a staging area, while naming
ids only empties them.
A struct is matched by its id, so a partial struct carrying just the right id is enough to remove
a record.
Returns the list of staging ids affected.
Releases the staged structs into the channel — each is ticked individually. Passing no ids releases
every staging area. Returns {staging_id: [structs]}.
A released staging area is dropped, not archived: its contents have been delivered on the channel
and on the release event, so it no longer appears in stage_list or stage_lookup.
stage_list returns the pending staging ids, or [staging_id] if that one is pending and [] if it
is not. stage_lookup returns {staging_id: [structs]} for the pending areas.
Each staged channel is mounted under /api/v1/stage/{channel} by MountRestRoutes. The id query
parameter is a comma-separated list of staging ids; omitting it is the unset case above, and passing
it empty (?id=) is the empty-list case.
| Method | Operation |
|---|---|
POST |
stage_add — body is the struct, or empty to open a staging |
DELETE |
stage_remove — body is the struct, or empty to empty/drop |
PATCH |
stage_release |
GET |
stage_list |
PUT |
stage_lookup |
A validator rejecting a staged struct surfaces as a 422; see
Develop.
Every staging mutation is published as a ts[StagingEvent] delta stream, one tick per affected
record:
events = channels.get_stage_events("orders") # ts[StagingEvent]| Field | Meaning |
|---|---|
channel |
The staged channel |
staging_id |
The staging area affected |
action |
CREATED, ADDED, REMOVED or RELEASED
|
items |
The record involved, or every released record for RELEASED
|
CREATED carries no items, and a staging area that is dropped reports a REMOVED per record followed
by a REMOVED with no items for the area itself.
This makes staging composable. A module can watch one channel's staging, build its own on another channel, and follow the upstream release:
@csp.node
def mirror(events: ts[StagingEvent], channels: object, field: str) -> None:
if csp.ticked(events):
if events.action == StagingAction.ADDED:
for item in events.items:
channels.stage_add(field, hedge_for(item))
elif events.action == StagingAction.RELEASED:
channels.stage_release(field)Staging can also be mutated from a timeseries, as the graph-native counterpart to calling
stage_add/stage_remove/stage_release directly:
channels.set_stage_requests("orders", requests) # ts[StagingRequest]A StagingRequest carries an action (the same four), the items to stage or unstage, and
staging_ids. Leaving staging_ids unset means the unset case above; setting it to an empty list
means the empty-list case. A REMOVED request with no items empties rather than unstaging a record.
This wiki is autogenerated. To made updates, open a PR against the original source file in docs/wiki.
Get Started
Key Components
For Developers
Modules
- API/UI Modules
- Logging Modules
- Replay Engine Modules
- Utility Modules
For Contributors