Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cron setup for retrieving live sports scores

I'm developing a mobile app that display the live scores for premiership football games. When a game starts, I want to query an external API every 30 seconds to retrieve the latest scores. Most games start at 3pm on a saturday, but some start at 12.45pm, others at 1.30pm, 2pm and 3pm on Sundays and some during the week at the latest time of 8pm.

I have a table in my database populated with all the fixtures for the season and the times they start at.

So I'm guessing I need a cron that runs every 15 minutes between 12.45 and 8pm (games never start outside of these times) that checks my database to see if a game is starting. Then, if there is a game starting, another cron must begin that queries the external API every 30 seconds for the latest score in that game. This cron would run for approximately 1 hour and 45 minutes.

What would be the best way to achieve this sort of cron setup? I'm on a shared server with Plesk software running on it, and don't have ssh access to the server.

like image 594
user1716672 Avatar asked Oct 30 '13 14:10

user1716672


2 Answers

Judging by one of your comments

the main problem is I'm on a shared server with no ssh access...

I think the issue here is you don't have access to the command shell and can only render your files to the server using Plesk. Hence, to render your solution, you are going to use cron jobs.

In that case, I will recommend double-checking with your hosting provider for any restrictions on number of cron jobs you can run / minimum frequency permitted for cron jobs. If there are restrictions on processing of cron jobs, you can use an online cron scheduler (like this). Note that external cron service will only allow hitting publicly accessible urls, so you will need to write and deploy code accordingly.

Hence forth, I will assume your cron jobs are working and there are no issues with them.

When a game starts, I want to query an external API every 30 seconds to retrieve the latest scores. Most games start at 3pm on a saturday, but some start at 12.45pm, others at 1.30pm, 2pm and 3pm on Sundays and some during the week at the latest time of 8pm.

Approach 1

Use a single updateMatchesAndScores.php file to update match information for any new matches (mark in the db as active/closed), and update scores for currently active matches.

Cron jobs can not handle the logic of the kind if match is on only then run this, that logic has to go to a script.

You can then run it from 12-10 PM like following

* 12-22 * * * php -f updateMatchesAndScores.php
* 12-22 * * * sleep 30 && php -f updateMatchesAndScores.php

In case of url http://some.server.address.com/updateMatchesAndScores, this becomes

* 12-22 * * * wget http://some.server.address.com/updateMatchesAndScores
* 12-22 * * * sleep 30 && wget http://some.server.address.com/updateMatchesAndScores

You can break this into multiple cron jobs (12.45-12.59, 13:00-20:59, 21:00-21:45) assuming games happen in time range [12.45, 21:45]. This will optimize the unnecessary runs from 12.00-12.45 and so on.

Approach 2

Start a daemon process once using a one time cron job, and then check every minute if its still running or not.

Lets call the script updateMatchesAndScores.php. Put the sleep functionality in this for (1) 15 minutes if no game is on (2) 30 seconds if any game is on in this (3) Sleep from 21:46 to 12:44 next day. You can spawn a separate sub process for every game, so that you don't have to implement (2) for sleeping every 30 minutes in this script.

Caveats - (1) the execution time of the script will start delaying the code a bit, so 15 minutes will soon turn into 15 minutes and x seconds (2) There is a max execution time within php, so you will have to set it accordingly (3) Based on your code quality, there might be memory leaks affecting you slightly.

An optimization here could be to run the process every day using a cron job (which stops after the last game is over - irrespective of whether its 21:46 or 4:30) and restart it accordingly if not already running.

like image 196
Anshul Goyal Avatar answered Sep 26 '22 10:09

Anshul Goyal


It might be more straightforward to have just one cron job, that looks for game start times, as you have suggested, but which then starts a job for each game that runs for the entire length of the game, looping until the game is over, and sleeping for 30 seconds at the bottom of the loop.

like image 35
GreyBeardedGeek Avatar answered Sep 22 '22 10:09

GreyBeardedGeek