I Made a PHP Task Scheduler!
This is an experiment in creating a Job/Task Scheduler / Queue system in PHP and a little bit of Python! I'll be clear, I re-invented the wheel on this one. I did this project to help me think differently about creating applications as well as picking up a few new tricks. I started this project with the intent of getting into command line PHP, but morphed into creating a Task Scheduler ( kind of like creating a replacement for Windows Task Scheduler ). There are really good frameworks such as Laravel that has it's own Task/Queue system built in, and Symphony that can build good CLI.
I didn't build a full solution here. I only built out a few use cases such as being able to auto execute jobs/tasks that are scheduled to run within a 1 minute to 60 minute window (intervals). I didn't build out the ability to run jobs/tasks daily/monthly/yearly, but may add this at a later time.
The dashboard interface, which is built on Slim 3, you can see a list of Jobs, as well as see whats in the Queue. You can also hold/release jobs, add jobs to the queue for execution, and the usual CRUD.
This project uses the following:
-PHP 5.5.12 +
-PHP PDO Extension
-Python 3.5.2 +
-Slim 3 + dependencies
The interesting thing about PHP is the ability to execute scripts via command line. Take this small script for example (lets call it example.php):
<?php echo "Hi, welcome to the command line\n";
To run, open a command prompt and type:
Running the above script should output "Hi, welcome to the command line" in the console!
Going off the ability to do command line, I created three major "commands" as parameters in my script (stphpschedule.php):
- check - checks the JOBS list table and determines if it's time to run, then insert into Queue
- execute - executes any job in the QUEUE table.
- builddb - builds SQLite database & mock jobs.
Executing the command: php stphpschedule.php check runs the "check" function. First, it will check a jobs interval and last run time. If the conditions are right, it then inserts a new entry into the QUEUE table. In the QUEUE table, a record will have the job name, it's path to the file, time in Queue, and hold status. The "execute" command simply verifies the file exsists, makes sure the job is not on hold ( via a flag in a field ) and then executes.
Feel free to browse the source of the "cli" directory in the project files or on github.
For the sake of this experiment, I segmented the ability to "check" and "execute" into their own cli commands. I did this as more of a way to test jobs going in and out of the queue. Originally, I set up Windows Task Scheduler to execute both commands, but I didn't like how the lowest interval on a Task Scheduler task is at 1 minute. So I created a small Python script to run these commands at a shorter interval!
listen.py was created to fill in the gaps of Windows Task Scheduler executing the commands I created. This short script runs a continuous loop ( with some pauses in between, this can be adjusted by editing time.sleep(seconds) values ):
while True: try: cmd = "php -f stphpschedule.php check" p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) print ("Checking queue php script..") print (p) time.sleep(15) exe = "php -f stphpschedule.php execute" p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) time.sleep(5) except Exception as e: print (e) print ("Something happened!")
It's probably not the best way to implement, but I really only needed the short execution time of my commands! If you run this in Python IDLE ( press F5 ), the "check" and "execute" commands will run.
The dashboard was built using the Slim 3 framework. I used HelloSlim3 project as scaffolding and only consists of one page. I used MVC with this portion of the app along with Eloquent ORM! I also created various API routes for the typical create/update/delete operations.
I wasn't intending on doing a full code tutorial with this tinker project. Just to merely show it off. I'm not intending to release this as a official open source project of any kind. This is just an experiment to get a working solution! Head over to the Github project and download or experiment for yourself!
Thanks for reading! --Drew