You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Please vote on this issue by adding a
π reaction to the original
issue to help the community and maintainers prioritize this request
Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra
noise for issue followers and do not help prioritize the request
If you are interested in working on this issue or have submitted a pull request, please leave a comment
Description
pulsar_function cannot create a window function. WindowConfig is the one substantial Pulsar Functions capability with no representation in the resource at all β not a tuning knob, but a different processing model: a window function receives a collection of messages over a tumbling or sliding window rather than one message at a time.
utils.FunctionConfig has a WindowConfig *WindowConfig field and the admin client models the type fully:
marshalFunctionConfig never populates it (grep -c WindowConfig pulsar/resource_pulsar_function.go returns 0), so it is always sent nil. A user who needs windowing has to create the function with pulsar-admin and leave it outside Terraform β which for anyone managing Pulsar as code means that function is unmanaged, and a subsequent terraform apply cannot see or preserve its window settings.
I found this while auditing every utils.FunctionConfig field against what the resource sets: 45 fields, 35 populated. Of the 10 that are not, two are addressed by open PRs (#219 for InputSpecs, #223 for ProducerConfig), three look derived rather than user-facing (FQFN, Runtime, FunctionType), and four are minor tuning knobs (MaxPendingAsyncRequests, ExposePulsarAdminClientEnabled, RuntimeFlags, the top-level BatchBuilder). WindowConfig is the only one that gates a capability rather than a setting, which is why it is filed on its own.
No upstream dependency. The type is already in the pinned admin client, so this is purely provider work.
Scope: window functions are Java-only
Worth stating before anyone implements this, because it narrows the value and suggests a validation the provider should carry.
Windowing is not a per-runtime capability that Python and Go merely lack β it is a Java-runtime implementation. In FunctionConfigUtils.convert(), a non-null windowConfig causes the broker to stash the config into userConfig under WINDOW_CONFIG_KEY, move the user's class into actualWindowFunctionClassName, and then replace className with org.apache.pulsar.functions.windowing.WindowFunctionExecutor β a Java class no other runtime can load.
Accordingly the broker refuses it outright for the other two:
// FunctionConfigUtils.doPythonChecks()if (functionConfig.getWindowConfig() != null) {
thrownewIllegalArgumentException("There is currently no support windowing in python");
}
// FunctionConfigUtils.doGolangChecks()if (functionConfig.getWindowConfig() != null) {
thrownewIllegalArgumentException("Windowing is not supported in Go function yet");
}
Two consequences:
This issue only benefits Java functions. Still worth doing β a jar-based function is a first-class case for the resource β but it is not the general capability the original description implied.
The provider should reject the combination at plan time. A configuration setting window_config alongside py or go is guaranteed to fail at apply with the broker's exception. Catching it in CustomizeDiff turns that into a plan-time error naming the actual constraint, which is the same treatment input_specs gets in feat(function): expose input_specs for per-topic consumer configΒ #219 for the schema/serde exclusivity the broker enforces.
Note also that the broker forces processingGuarantees to MANUAL on the function and moves the configured value onto the window config, and rejects EFFECTIVELY_ONCE and MANUAL outright when windowing is set. That interacts with the existing top-level processing_guarantees attribute and is the substance of point 4 below.
New or Affected Resource(s)
pulsar_function
Potential Terraform Configuration
A window_config block, following the sink_config / source_config precedent already in the resource:
Count versus duration are mutually exclusive per axis.windowLengthCount and windowLengthDurationMs cannot both be set, and neither can the two sliding-interval fields. Pulsar validates this server-side; catching it at plan time would give a better error, in the same way input_specs validates schema/serde exclusivity in feat(function): expose input_specs for per-topic consumer configΒ #219.
actualWindowFunctionClassName is set by the worker, not the user β it records the user's class while className becomes the framework's window wrapper. It probably wants to be Computed rather than configurable, but that is worth confirming against the broker's behaviour rather than assumed.
ProcessingGuarantees appears both here and at the top level. Which wins, and whether the block's copy should be exposed at all, needs deciding.
Community Note
π reaction to the original
issue to help the community and maintainers prioritize this request
noise for issue followers and do not help prioritize the request
Description
pulsar_functioncannot create a window function.WindowConfigis the one substantial Pulsar Functions capability with no representation in the resource at all β not a tuning knob, but a different processing model: a window function receives a collection of messages over a tumbling or sliding window rather than one message at a time.utils.FunctionConfighas aWindowConfig *WindowConfigfield and the admin client models the type fully:marshalFunctionConfignever populates it (grep -c WindowConfig pulsar/resource_pulsar_function.goreturns 0), so it is always sent nil. A user who needs windowing has to create the function withpulsar-adminand leave it outside Terraform β which for anyone managing Pulsar as code means that function is unmanaged, and a subsequentterraform applycannot see or preserve its window settings.I found this while auditing every
utils.FunctionConfigfield against what the resource sets: 45 fields, 35 populated. Of the 10 that are not, two are addressed by open PRs (#219 forInputSpecs, #223 forProducerConfig), three look derived rather than user-facing (FQFN,Runtime,FunctionType), and four are minor tuning knobs (MaxPendingAsyncRequests,ExposePulsarAdminClientEnabled,RuntimeFlags, the top-levelBatchBuilder).WindowConfigis the only one that gates a capability rather than a setting, which is why it is filed on its own.No upstream dependency. The type is already in the pinned admin client, so this is purely provider work.
Scope: window functions are Java-only
Worth stating before anyone implements this, because it narrows the value and suggests a validation the provider should carry.
Windowing is not a per-runtime capability that Python and Go merely lack β it is a Java-runtime implementation. In
FunctionConfigUtils.convert(), a non-nullwindowConfigcauses the broker to stash the config intouserConfigunderWINDOW_CONFIG_KEY, move the user's class intoactualWindowFunctionClassName, and then replaceclassNamewithorg.apache.pulsar.functions.windowing.WindowFunctionExecutorβ a Java class no other runtime can load.Accordingly the broker refuses it outright for the other two:
Two consequences:
jar-based function is a first-class case for the resource β but it is not the general capability the original description implied.window_configalongsidepyorgois guaranteed to fail at apply with the broker's exception. Catching it inCustomizeDiffturns that into a plan-time error naming the actual constraint, which is the same treatmentinput_specsgets in feat(function): expose input_specs for per-topic consumer configΒ #219 for the schema/serde exclusivity the broker enforces.Note also that the broker forces
processingGuaranteestoMANUALon the function and moves the configured value onto the window config, and rejectsEFFECTIVELY_ONCEandMANUALoutright when windowing is set. That interacts with the existing top-levelprocessing_guaranteesattribute and is the substance of point 4 below.New or Affected Resource(s)
Potential Terraform Configuration
A
window_configblock, following thesink_config/source_configprecedent already in the resource:Points worth settling in review:
windowLengthCountandwindowLengthDurationMscannot both be set, and neither can the two sliding-interval fields. Pulsar validates this server-side; catching it at plan time would give a better error, in the same wayinput_specsvalidates schema/serde exclusivity in feat(function): expose input_specs for per-topic consumer configΒ #219.receiver_queue_size = 0unrepresentable until fix(pulsaradmin): preserve explicit zero receiver queue sizeΒ apache/pulsar-client-go#1529.actualWindowFunctionClassNameis set by the worker, not the user β it records the user's class whileclassNamebecomes the framework's window wrapper. It probably wants to beComputedrather than configurable, but that is worth confirming against the broker's behaviour rather than assumed.ProcessingGuaranteesappears both here and at the top level. Which wins, and whether the block's copy should be exposed at all, needs deciding.References
input_specs, the same class of gap on the consumer sideproducerConfig, the same class of gap on the producer side