feat(perl): add script commands trigger - #446
Conversation
|
thanks for the PR, it seems you also did #432 in the same time? could you remove the commit and open its own PR? (and comment on issue so I can assign you) |
The R ScriptTrigger/CommandsTrigger in this branch are byte-for-byte identical to PR kestra-io#438, which is dedicated to the R module. Remove them here so kestra-io#446 is scoped to the Perl triggers and kestra-io#438 owns the R work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Hi @Abhishek84313 I dropped your modification on R script, as they already are on another PR |
jymaire
left a comment
There was a problem hiding this comment.
Two inline findings from review: a blocking ReDoS gap in matchesCondition and a note on non-persisted edge state.
Run the user-supplied exitCondition regex with a 5s timeout and fall back to substring matching, as the Ruby/Shell/Node/Bun triggers do, so a catastrophic-backtracking pattern can no longer hang the scheduler poll thread. Document the in-memory edge-state limitation and add condition tests for pathological and invalid regexes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ample
(a+)+$ is memoized by the JDK 25 regex engine and fails instantly, so the
test never reached the 5s guard; use (.*a){20}$ and assert the elapsed
time. The CommandsTrigger example ran `perl missing.pl`, which exits 2 and
never matched `exit 1`; use `perl -e 'exit 1'` instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The in-memory lastMatched flag was rebuilt with the trigger on every poll, so edge mode fired on every matching poll. Keep the previous result in the namespace KV store instead, as the Bun/.NET/PowerShell triggers do. Replaces the tautological AtomicBoolean edge tests with EdgeStateTest and an evaluate-level test that polls through a serialized copy. Refs kestra-io#449 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
QA report — Perl ScriptTrigger / CommandsTriggerEdition: OSS | Docker tag: v1.3.39 | PR head: 0ba7de7 Summary
Edge mode, before vs after 0ba7de7 (
Flow 1: script_trigger (✅)Flow YAMLid: script_trigger
namespace: company.team
triggers:
- id: script_failure
type: io.kestra.plugin.scripts.perl.ScriptTrigger
interval: PT10S
exitCondition: "exit 1"
edge: true
containerImage: perl
script: |
# This fails with a non-zero exit code.
exit 1;
tasks:
- id: log
type: io.kestra.plugin.core.log.Log
message: "Triggered with exitCode={{ trigger.exitCode }} (condition={{ trigger.condition }})"Executions (screenshot): 1 execution (SUCCESS, 0.49 s) after enabling on 0ba7de7, none after restart. Earlier rows are the f613113 build firing every ~10 s. Logs synthesis: Trigger outputs: Flow 2: commands_trigger (✅)Flow YAMLid: commands_trigger
namespace: company.team
triggers:
- id: commands_failure
type: io.kestra.plugin.scripts.perl.CommandsTrigger
interval: PT10S
exitCondition: "exit 1"
edge: true
containerImage: perl
commands:
- perl -e 'exit 1'
tasks:
- id: log
type: io.kestra.plugin.core.log.Log
message: "Triggered with exitCode={{ trigger.exitCode }} (condition={{ trigger.condition }})"Executions (screenshot): 1 execution (SUCCESS, 0.53 s) on 0ba7de7, none after restart. Trigger outputs: Flow 3: commands_trigger_vars (✅)Flow YAMLid: commands_trigger_vars
namespace: company.team
triggers:
- id: on_perl_commands
type: io.kestra.plugin.scripts.perl.CommandsTrigger
interval: PT10S
exitCondition: "toto"
edge: true
containerImage: perl
commands:
- echo '::{"outputs":{"listing":"toto"}}::'
tasks:
- id: log
type: io.kestra.plugin.core.log.Log
message: "Triggered with vars={{ trigger.vars }}"Executions (screenshot): 1 execution on 0ba7de7, none after restart. Logs synthesis (screenshot): Trigger outputs: Edge state (screenshot): one KV key per trigger in Flow 4: script_trigger_redos (✅
|
| Task | Status | Duration |
|---|---|---|
perl |
SUCCESS | 0.58s |
| Total | SUCCESS | 0.58s |
Logs synthesis: hello from perl 5.044000, Command succeed with exit code 0, no WARN/ERROR.
Outputs synthesis (screenshot): vars.answer: 42, exitCode: 0.
Timeouts
None.
Tests
./gradlew :plugin-script-perl:test --rerun-tasks on 0ba7de7: 53 passed, 0 failed.
jymaire
left a comment
There was a problem hiding this comment.
I edited PR to apply fixes so the PR doesn't stay stale. Thanks for your contribution!
|
@jymaire Thank you |
What changes are being made and why?
Adds
ScriptTriggerandCommandsTriggertoplugin-script-perl, so a flow can be triggered when a Perl script or set of Perl commands completes, with an exit condition deciding whether the trigger fires.plugin-script-perlwas the last of the scripting submodules missing both. This follows the existing implementations inplugin-script-go,plugin-script-node,plugin-script-python,plugin-script-ruby,plugin-script-shellandplugin-script-r— same package as the task classes, no nested subpackage, and the same property set (containerImage,script/commands,exitCondition,interval,edge).Both triggers implement
PollingTriggerInterfaceand emit an output carrying the timestamp, the rendered condition, the exit code and any structuredvars; execution id, namespace and flow id come fromTriggerService.generateExecution.exitConditionaccepts eitherexit N(compared against the exit code) or a regex, with a substring fallback when the regex is invalid, matched against emitted vars and failure logs.edgemode (defaulttrue) emits only on a transition from not-matching to matching, so a persistently failing script does not fire on every poll.Part of #313. Closes #429.
One deviation from the issue worth flagging for review: #429 proposes
commandPattern/argumentsPattern/exitCondition, but every existing submodule uses thecontainerImage/script-or-commands/exitCondition/interval/edgeshape, where the trigger runs the script rather than matching a pattern against externally observed executions. I followed the established convention for consistency. If the schema in the issue is the intended direction, it is a change across all submodules and is probably better settled separately.How the changes have been QAed?
ScriptTrigger— fires when the script exits non-zero: