Understanding Conditions
Conditions are expressions that must be true before job can start. Each job supports up to 10 conditions.
Condition structure:
variable_name operator value
Operators:
- = equal to
- != not equal to
- < less than
- <= less than or equal
- > greater than
- >= greater than or equal
Simple Condition Examples
bash
# Wait for backup to complete btr -c "backup_status = Complete" post-backup.sh # Wait for counter to reach threshold btr -c "processed_count >= 100" summary.sh # Wait for status NOT pending btr -c "status != Pending" process.sh # Numeric comparison btr -c "error_count < 5" continue.sh
Multiple Conditions
Jobs can have up to 10 conditions - ALL must be true:
bash
# Must meet all conditions
btr -c "backup_status = Complete" \
-c "validation_status = Passed" \
-c "error_count = 0" \
final-report.sh
Job won't start until all three conditions satisfied.
Remote Variable Conditions
Reference variables on other hosts:
bash
# Wait for variable on server1
btr -c "server1:backup_status = Complete" local-job.sh
# Multiple remote conditions
btr -c "server1:data_ready = Yes" \
-c "server2:data_ready = Yes" \
merge-data.sh
Critical vs Non-Critical Conditions
Critical (default):
Job blocks if remote host unavailable.
Non-critical:
Condition ignored if remote host unavailable.
bash
# If server1 down, condition ignored btr -c "server1:optional_check = OK" process.sh # Mark as non-critical in btq when editing conditions
Use critical for:
- Essential dependencies
- Production workflows
Use non-critical for:
- Optional checks
- Monitoring scenarios
- When remote host may be down
Understanding Assignments
Assignments change variable values when job runs. Each job supports up to 8 assignments.
Assignment operations:
Set (=) : Assign value to variable
Add (+=) : Add to numeric variable
Subtract (-=) : Subtract from numeric variable
Multiply (*=) : Multiply numeric variable
Divide (/=) : Divide numeric variable
Modulus (%=) : Modulus on numeric variable
Assignment Timing Flags
Assignments execute based on flags:
S (Start) : Perform when job starts
N (Normal exit) : Perform when job completes successfully (exit code 0)
E (Error exit) : Perform when job exits with error (exit code non-zero)
A (Abort) : Perform when job aborted by signal
C (Cancel) : Perform when job cancelled before running
R (Reverse) : Undo assignment when job ends (requires exit flag)
Simple Assignment Examples
Update status on start/complete:
bash
btr -A "status = Running @ Job start" \
-A "status = Complete @ Job completed" \
job.sh
Increment counter on start:
bash
btr -A "job_count += 1 @ Job start" job.sh
Set different status based on outcome:
bash
btr -A "status = Running @ Job start" \
-A "status = Success @ Job completed" \
-A "status = Failed @ Job error" \
job.sh
Acquire and release lock:
bash
btr -A "lock = 1 @ Job start" \
-A "lock = 0 @ Job completed" \
critical-section.sh
Reverse Flag
Reverse flag undoes assignment when job ends:
bash
# Acquire lock on start, release on any exit
btr -A "lock = 1 @ Job start, Reverse" critical.sh
# Equivalent to:
btr -A "lock = 1 @ Job start" \
-A "lock = 0 @ Job completed" \
-A "lock = 0 @ Job error" \
-A "lock = 0 @ Job abort" \
critical.sh
Use reverse for:
- Resource locks
- Semaphore patterns
- Temporary state changes
Exit Code Capture
Special assignments capture job's exit code or signal:
Exit code:
bash
btr -A "exit_code = Exit Code @ Job completed" job.sh # Variable exit_code will contain actual exit code
Signal number:
bash
btr -A "term_signal = Signal @ Job abort" job.sh # Variable term_signal contains signal number if killed
Workflow Patterns
Sequential Job Chain
bash
# Job 1: Sets status when complete
btr -A "step1_done = Yes @ Job completed" step1.sh
# Job 2: Waits for step1, sets status when complete
btr -c "step1_done = Yes" \
-A "step2_done = Yes @ Job completed" \
step2.sh
# Job 3: Waits for step2
btr -c "step2_done = Yes" step3.sh
Mutual Exclusion Lock
bash
# Create lock variable
btvar -c db_update_lock 0
# Jobs acquire lock
btr -c "db_update_lock = 0" \
-A "db_update_lock = 1 @ Job start" \
-A "db_update_lock = 0 @ Job completed, Job error" \
update-db.sh
Only one job can run at a time (waits for lock = 0).
Fan-Out Pattern
bash
# Parent job spawns children btr -A "parent_done = Yes @ Job completed" parent.sh # Multiple child jobs wait for parent btr -c "parent_done = Yes" child1.sh btr -c "parent_done = Yes" child2.sh btr -c "parent_done = Yes" child3.sh
Fan-In Pattern
bash
# Multiple inputs set completion flags
btr -A "input1_ready = Yes @ Job completed" input1.sh
btr -A "input2_ready = Yes @ Job completed" input2.sh
btr -A "input3_ready = Yes @ Job completed" input3.sh
# Final job waits for all inputs
btr -c "input1_ready = Yes" \
-c "input2_ready = Yes" \
-c "input3_ready = Yes" \
merge-all.sh
Counter with Threshold
bash
# Initialize counter
btvar -c file_count 0
# Jobs increment counter
btr -A "file_count += 1 @ Job completed" \
process-file.sh
# Summary runs when threshold reached
btr -c "file_count >= 100" \
-A "file_count = 0 @ Job start" \
generate-summary.sh
State Machine
bash
# Create state variable
btvar -c workflow_state "Initialize"
# Job transitions through states
btr -c "workflow_state = Initialize" \
-A "workflow_state = Extract @ Job completed" \
initialize.sh
btr -c "workflow_state = Extract" \
-A "workflow_state = Transform @ Job completed" \
extract.sh
btr -c "workflow_state = Transform" \
-A "workflow_state = Load @ Job completed" \
transform.sh
btr -c "workflow_state = Load" \
-A "workflow_state = Complete @ Job completed" \
load.sh
Remote Assignments
Modify variables on other hosts:
bash
# Update variable on server1
btr -A "server1:import_complete = Yes @ Job completed" \
export-data.sh
# Job on server1 waits for this variable
Mark as critical if assignment must succeed.
Complex Example: Production Workflow
bash
# Variables
btvar -c extract_status "Not Started"
btvar -c extract_count 0
btvar -c transform_status "Not Started"
btvar -c load_status "Not Started"
# Extract job (runs daily 01:00)
btr -t "01:00" -r Days:1 \
-A "extract_status = Running @ Job start" \
-A "extract_count += 1 @ Job start" \
-A "extract_status = Complete @ Job completed" \
-A "extract_status = Failed @ Job error" \
extract-data.sh
# Transform job (waits for extract)
btr -c "extract_status = Complete" \
-A "transform_status = Running @ Job start" \
-A "transform_status = Complete @ Job completed" \
-A "transform_status = Failed @ Job error" \
-A "extract_status = Not Started @ Job completed" \
transform-data.sh
# Load job (waits for transform)
btr -c "transform_status = Complete" \
-A "load_status = Running @ Job start" \
-A "load_status = Complete @ Job completed" \
-A "load_status = Failed @ Job error" \
-A "transform_status = Not Started @ Job completed" \
load-data.sh
# Alert job (runs if any step fails)
btr -c "extract_status = Failed" \
-A "extract_status = Not Started @ Job completed" \
send-alert.sh
btr -c "transform_status = Failed" \
-A "transform_status = Not Started @ Job completed" \
send-alert.sh
btr -c "load_status = Failed" \
-A "load_status = Not Started @ Job completed" \
send-alert.sh
Best Practices
Use descriptive variable names:
- backup_complete better than bc
- db_lock better than lock1
Reset status variables:
After final job completes, reset statuses for next cycle.
Set status on all exit types:
bash
# Good - handles all cases -A "status = Running @ Job start" \ -A "status = Success @ Job completed" \ -A "status = Failed @ Job error, Job abort" # Bad - doesn't handle abort -A "status = Running @ Job start" \ -A "status = Done @ Job completed"
Document complex workflows:
Add comments to job titles explaining dependencies.
Test conditions thoroughly:
Verify conditions work as expected before production.
Limit condition/assignment complexity:
If workflow needs > 10 conditions or 8 assignments per job, consider breaking into smaller jobs.