DEV Community

Cover image for Schedule and Signal: Dynamic Python Task Management
AissaGeek
AissaGeek

Posted on

Schedule and Signal: Dynamic Python Task Management

Introduction

Ever had a Python script running via cron and wished you could communicate with it on the fly? This article introduces a Python project where a cron job runs a Python script, and that script then awaits signals to call specific methods.

Prerequisites

  • Basic knowledge of Python.
  • Familiarity with Unix/Linux systems.
  • A Python environment.

Step 1: The Python Project

import os
import signal
import sys
import time

def main_task():
    print("Performing the main task...")
    # Your task logic here

def handle_signal(signum, frame):
    print(f"Received signal {signum}, executing special task...")
    # Additional task logic here

if __name__ == "__main__":
    # Assign signal handlers
    signal.signal(signal.SIGUSR1, handle_signal)
    signal.signal(signal.SIGUSR2, handle_signal)

    while True:
        main_task()
        time.sleep(60)  # sleep for 60 seconds
Enter fullscreen mode Exit fullscreen mode

Our script performs a main_task() once every minute. But, with the magic of signal handling, it can respond to signals and perform special tasks even while it's waiting!

Understanding Signal Handling

Signals are software interrupts sent to a program to indicate that an important event has occurred. In this script, we're handling SIGUSR1 and SIGUSR2 signals. When these signals are detected, our handle_signal method gets executed.

Step 2: Scheduling with cron

Introduction to Cron

cron is a job scheduler in Unix-like systems, used to run commands or scripts at fixed times, dates, or intervals.

Scheduling Your Python Script

To schedule your Python script to run every hour, you can use the following cron command:

0 * * * * /usr/bin/python3 /path/to/your_script.py
Enter fullscreen mode Exit fullscreen mode

Each field has a specific meaning and allows you to configure exactly when and how often the task should be executed. Hereโ€™s a breakdown of what each field means:

  • 0: Minute (0 - 59)
  • *: Hour (0 - 23)
  • *: Day of month (1 - 31)
  • *: Month (1 - 12)
  • *: Day of week (0 - 6) (Sunday=0 or 7)
  • /usr/bin/python3 /path/to/your_script.py: Command to be executed

So, 0 * * * * /usr/bin/python3 /path/to/your_script.py translates to:
"Run /path/to/your_script.py with /usr/bin/python3 at minute 0 of every hour of every day of the month, every month, and every day of the week."

Breaking Down the Timing:

  • 0: The task runs at the zeroth minute of the hour.
  • *: The task runs every hour.
  • *: The task runs every day of the month.
  • *: The task runs every month.
  • *: The task runs every day of the week.

Step 3: Dynamically Interacting with the Running Script

Once our Python script is running, you can send signals to it. Here's how:

Find the Process ID (PID)

ps aux | grep your_script.py
Enter fullscreen mode Exit fullscreen mode

Send a Signal

kill -USR1 [PID]
Enter fullscreen mode Exit fullscreen mode

Replace [PID] with the actual process ID from step 1.

Step 4: Use Cases

Imagine a data ingestion script that pulls data every hour. Midway, you realize you want to trigger an additional data cleaning method without stopping the script. Signals allow you to do just that!

You could extend this to various scenarios:

  1. Dynamically modifying configuration.
  2. Logging diagnostics.
  3. Graceful shutdowns.
  4. Troubleshooting
  5. No Logs: Ensure your Python script has appropriate logging.
  6. Unhandled Signals: Your script will terminate if it receives unhandled signals. Ensure signal handling covers expected signals.
  7. Script Failures: Monitor the health of your script. Consider adding health checks or alerts.

Conclusion

Dynamic task management in Python, with the combination of cron and Unix signals, offers a powerful tool in the developer's arsenal. It's a great method to have long-running scripts that can adapt to changing needs on the fly. Dive in, and > Follow up for more, your support makes me high :D

Further Reading

  • Pythonโ€™s signal documentation
  • Crontab Guru

Top comments (0)