Add functionality to trigger tasks on specific events with batching
Implementation: Event-triggered task execution
This PR implements a complete event trigger system that allows workflows to automatically spawn tasks when specific output items match certain conditions. Items are batched and tasks are triggered either when the batch reaches a specified size or after a timeout period.
Features Implemented
- Event matching: Tasks can watch for specific output types (url, port, subdomain, etc.) with optional Python condition expressions
- Batching system:
- Count-based triggering (when batch reaches
batch_size) - Time-based triggering (after
batch_timeoutseconds if batch isn't full)
- Count-based triggering (when batch reaches
- Thread-safe implementation: Uses lazy-initialized RLock for safe concurrent access
- Celery-compatible: All non-serializable objects (locks, timers) are lazy-initialized to maintain serializability
Configuration Example
tasks:
httpx:
description: Probe URLs
bup:
description: Auto-bypass 403 URLs
on_event:
type: url
condition: item.status_code == 403
batch_size: 5
batch_timeout: 30
targets_:
- type: url
field: url
Implementation Details
- Runner Base Class (
secator/runners/_base.py): Core event trigger logic with registration, matching, batching, and timer management - Workflow Class (
secator/runners/workflow.py): Override to parseon_eventconfiguration and spawn actual tasks with batched items - Integration: Reuses existing
targets_mechanism for input extraction from batched items
Testing
- 7 comprehensive tests covering all functionality (6 unit + 1 integration)
- All existing tests still passing
- Example workflow:
secator/configs/workflows/url_bypass_auto.yaml
Documentation
- Complete implementation guide in
EVENT_TRIGGERS.md - Inline YAML comments explaining configuration options
- Real-world example demonstrating auto-bypass of 403 URLs
This addresses both requirements from issue #384:
-
✅ Run a task on certain events (e.g., run bypasser on all url.status_code == 403)
-
✅ Batch those events and execute after a given period of time if less events than the batch
-
Fixes freelabz/secator#384
Original prompt
This section details on the original issue you should resolve
<issue_title>feat(runner): trigger task on certain events</issue_title> <issue_description>It would be nice to be able to:
- [ ] Run a task on a given event (e.g run bypasser on all url.status_code == 403)
- [ ] Batch those events and execute after a given period of time if less events than the batch</issue_description>
Comments on the Issue (you are @copilot in this section)
- Fixes freelabz/secator#384
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.
[!IMPORTANT]
Review skipped
Bot user detected.
To trigger a single review, invoke the
@coderabbitai reviewcommand.You can disable this status message by setting the
reviews.review_statustofalsein the CodeRabbit configuration file.
Comment @coderabbitai help to get the list of available commands and usage tips.
Retry now. Make sure you use lazy initialisation for objectif like threading lock, otherwise they won't be serializable when the runner instance is passed to Celery.
Fixed in 26c7d2a. Changed to use lazy initialization via a property - the event_lock is now created on first access using a @property decorator, keeping _event_lock as None during initialization. This allows the Runner instance to be serialized when passed to Celery.
@copilot Ok now implement the rest of the PR
@copilot Ok now implement the rest of the PR
Implemented in commits ae56e62, edf34a8, and 20bd614.
The event trigger system is now complete with:
Core functionality:
- Event matching with conditions (e.g.,
item.status_code == 403) - Batching with count-based (batch_size) and time-based (batch_timeout) triggers
- Automatic task spawning with batched items as inputs
- Thread-safe with lazy-initialized RLock
Configuration example:
tasks:
bup:
on_event:
type: url
condition: item.status_code == 403
batch_size: 5
batch_timeout: 30
targets_:
- type: url
field: url
Test coverage:
- 7 tests (6 unit + 1 integration), all passing
- All existing tests still passing
See EVENT_TRIGGERS.md for complete documentation and secator/configs/workflows/url_bypass_auto.yaml for a working example.