Back to Knowledege base

Controlling Job Flow with Conditions and Assignments

Creating dependencies and state changes using variables

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.

Controlling When Jobs Run with Time Settings
Understanding run times, repeat specifications, and avoiding days