graflo.hq.cast_pool¶
Worker-process casting for the ingestion hot path.
Casting a document is pure Python and never releases the GIL, so threads cannot
speed it up — they only add dispatch cost. This module moves the work into worker
processes, which is where IngestionParams.n_cores finally means cores.
Only declarative data crosses the boundary. :class:~graflo.architecture.pipeline.runtime.resource.ResourceRuntime
is schema-bound and explicitly not serializable, so each worker rebuilds its own
from the serialized ResourceConfig / VertexConfig / EdgeConfig once and
caches it; afterwards only plain documents travel in and plain entity payloads
travel back.
Attributes¶
WorkerChunkResult = tuple[dict[str, list], dict[Any, list], list[Any], list[tuple[int, list]], list[tuple[int, tuple[str, str, str]]]]
module-attribute
¶
logger = logging.getLogger(__name__)
module-attribute
¶
Classes¶
CastSpec
¶
Bases: BaseModel
Everything a worker needs to rebuild a resource runtime, as plain data.
Source code in graflo/hq/cast_pool.py
Attributes¶
allowed_vertex_names = None
class-attribute
instance-attribute
¶
edge_config
instance-attribute
¶
model_config = ConfigDict(frozen=True)
class-attribute
instance-attribute
¶
resource
instance-attribute
¶
strict_references = False
class-attribute
instance-attribute
¶
target_db_flavor = None
class-attribute
instance-attribute
¶
transforms = Field(default_factory=list)
class-attribute
instance-attribute
¶
vertex_config
instance-attribute
¶
WorkerCastError
¶
Bases: RuntimeError
A per-document failure carried back from a worker process.
Rebuilt from the worker's report rather than unpickled, so the original type name and traceback survive even when the exception itself would not.
Source code in graflo/hq/cast_pool.py
Functions:¶
cast_chunk(docs, post_filter_vertex_names, drop_empty_identity)
¶
Cast a contiguous slice of documents in this worker, in order, and fold.
Per-document exceptions are captured as data rather than raised: an exception raised here would fail the whole chunk, losing the documents around it, and not every exception survives pickling anyway.
The fold (GraphContainer.from_docs_list) and the post-cast filters run
here rather than in the parent: the fold is an associative, order-preserving
concat, so chunk-wise folding followed by in-order concatenation in the
parent yields the identical graph — while the serial parent-side cost that
used to cancel out the process-pool speedup disappears.
Source code in graflo/hq/cast_pool.py
default_worker_count(n_cores)
¶
Worker processes to run, bounded by the machine's actual CPUs.
init_worker(spec)
¶
Pool initializer: build this worker's runtime before any chunk arrives.
The runtime is held per process so it is built once, not once per chunk — and so the spec never has to travel again. Only documents cross after this.