Add optional Max Input Size guard to the write processors - #15
Merged
Merged
Conversation
PutVastDB/UpdateVastDB/DeleteVastDB read the whole FlowFile into memory (getContentsAsBytes) and decode it into an Arrow table before writing, so a large enough FlowFile exhausts the NiFi Python process and gets it OOM-killed - an unrecoverable crash rather than a routed failure. (The write itself is safe: the vastdb SDK already slices inserts into small RPCs, so the ceiling is client-side memory, not a server limit.) Add an opt-in "Max Input Size" property (DATA_SIZE_VALIDATOR, e.g. "500 MB"; empty = disabled). At the start of transform(), before any content is read, a FlowFile whose size exceeds the limit is routed to 'failure' with a vastdb.error attribute - the check reads only the FlowFile's size metadata, never getContentsAsBytes(). The ceiling is deliberately operator-set, not inferred: the safe size depends on the node's Python memory budget, concurrency, and the format's decode expansion, none of which the processor can reliably know (and reading cgroup limits or probing by allocation is unreliable). It is a safety tripwire, not a memory oracle - for bulk loads, split upstream (SplitRecord) or use ImportVastDB, which reads Parquet server-side. Shared logic lives in input_guard.py. Processor docs document the property and the rationale. 20 new unit tests; 48 pass overall. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G7cjFLk6huEsGcV6nG21n5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PutVastDB / UpdateVastDB / DeleteVastDB read the whole FlowFile into memory (
getContentsAsBytes) and decode it into an in-memory Arrow table before writing, so a large enough FlowFile exhausts the NiFi Python process and gets it OOM-killed — an unrecoverable crash, not a routed failure. (The write itself is safe: thevastdbSDK already slices inserts into ~4.5 MB RPCs, so the ceiling is client-side memory, not a server limit.)This adds an opt-in
Max Input Sizeproperty so an over-large FlowFile fails gracefully instead of crashing the interpreter.Behaviour
Max Input Size(required=False,DATA_SIZE_VALIDATOR, e.g.500 MB/2 GB; empty = disabled).transform(), before any content is read, ifflowfile.getSize() > limitthe FlowFile is routed tofailurewith avastdb.errorattribute. The check uses only the FlowFile's size metadata — it never callsgetContentsAsBytes(), so the guard itself allocates nothing.input_guard.py, used by all three write processors. ImportVastDB is intentionally excluded — its incoming FlowFile is just the small{key,bucket}list; the Parquet is read server-side.Design notes
The ceiling is operator-set, not inferred. The safe size depends on the node's Python memory budget, its concurrency, and the format's decode expansion (Parquet decompresses to many times its on-disk size), none of which the processor can reliably know — and reading cgroup limits or probing by allocation is unreliable (the OOM killer sends an uncatchable SIGKILL; Linux overcommit makes
MemoryErrorunreliable). So this is a safety tripwire, not a memory oracle. The docs steer bulk loads toSplitRecord(JVM-side streaming split) orImportVastDB(server-side read), where memory never depends on input size.Docs & tests
PutVastDB.md/UpdateVastDB.md/DeleteVastDB.mddocument the property and a "Guarding against large inputs" rationale section.failure). 48 pass overall;hatch fmt --checkclean.🤖 Generated with Claude Code
https://claude.ai/code/session_01G7cjFLk6huEsGcV6nG21n5