Managing Batch Jobs for Several Time Zones?
sporty asks: "I have one machine, a unix box, that serves many time zones at once. Because of this, everything is stored in GMT. Even the system clock is set relative to GMT. The problem is determining when midnite is. I need to run certain jobs, via cron or similar, so that something runs at midnite in that timezone. Anyone have this situation before?"
I'm curious why it has to run at midnight? Would it be so awful if it ran at 1am local time?
I suppose the obvious thing is to keep the local clocks at local time and set the job to run at midnight.
Use NTP to keep the clocks in sync.
One unix box. Multiple timezones. Evidently a different script needs to be run for each timezone, since otherwise you'd just run your script every half hour on the half hour...
Why not set up a set of groups with defined IDs (say maybe 1000 - 1047) for each timezone. Allocate users in the appropriate timezone to those groups
Run a master script every hour (or half hour) which su's to a dummy member of that group and runs some script. you get some protection from accidentally breaking things by running as root.
Care to tell us exactly what the obvious solutions don't do? what you're trying to do maybe?
/* affect != effect */ void affect(int *thing,int effect) { *thing += effect; }
-Find out what the GMT offset for each time zone is.
-Use that to figure out what GMT time is midnight for each time zone.
-Make a cron job for each time zone to run when it is midnight in that time zone.
Unless there is something about the question I don't understand...?
no thanks
Don't know if this advice applies to this guy or not, because he might truly have a need to run at exactly midnight. But please, run your cron jobs at randomly chosen times, instead of exactly on the hour. That way we can spread the load (machine and network) better. Thank you, have a nice day.
For each time zone, there's only going to be certain GMT times that can be "local" midnight. (Usually two.) So, at those times, you run a script that checks the "local" time, and, if it is actually midnight, runs the job! Simple, clean, sweet.
There's a tiny amount of overhead for running the check script at times that aren't local midnight, but that should be completely negligible.
Never heard of it.
Offtopic:
You may want to consider your use of midnight as a good time to run scripts.
Many people are still awake at this time, perhaps working from home, trying to beat a deadline, etc. Cron jobs using resources at this time could be frusturating, making a long night even longer.
You may want to consider moving jobs to 2 or 3 AM instead.
i.e.
Envy my 5 digit Slashdot User ID!
Just remember that when you have them run for each time zone, there is a thing called Daylight Savings Time in some time zones, and not in others. Depending on where your facilities might be, there are some places in Nevada for example that are in a Daylight Savings Time area, and other parts that are not. Just remember to offset those by an hour when DST occurs and when it goes back to normal time.
Alcohol & calculus don't mix. Never drink & derive.
I'd create a virtual-server for each timezone in question, it could have its own ntp tools managing the time, and its own cron to be the timer. Keep things nice and neat. In freebssd at least this could be done in a jail.
It isn't a lie if you belive it.
Check it out, it converts between timezones automagically, respects daylight savings, and all of the fun stuff.
It's really a lifesaver, here is a link DateTime.pm
Everybody has a purpose in life, maybe mine is to lurk in slashdot.
We have a similar problem and right now we are working on modifying the code for cron (vixie derived) to allow us to run multiple instances each with a different timezone. It's not a top priority for us but will post it somewhere, when it's done.
True friends are hard to come by... I need more money. - Calvin
However, there's another simple solution. Again, based on the fact that there's really only two times that can be local midnight. Simply run a script like this at the earlier of the two times:Note that hacking cron to respect timezones will result in the same bug as my earlier approach. So, this approach is really the cleanest I can see.
The problem with hacking cron to respect local time is that in local time, there is (once a year) a day with two midnights, and a day with none.
I think the best approach is the one I outlined here. Run at the earliest time that might be midnight, and if it's not yet midnight, sleep till it is.
Rather than trying to make cron do something it doesn't want to (which obviously won't work in this situation without modifying cron, not a good idea if you rely on it for other things), write a tiny program that does nothing more than load a list of GMT times at which it needs to do something, and executes a script associated with that time.
You'd need only one main config file, looking something like:
00:00 script.ut
16:00 script.pmt
19:00 script.edt
(blah, blah, blah)
And each individual script could have as much variation as you possibly want.
The program would take very close to no memory or CPU, needing only a few dozen time/scriptname pairs at most, and it would just sleep() 99.99999% of the time. Depending on what sort of security you need on the individual midnight events, you could write such a program in under 50 lines easily.
As for daylight savings, if you really need to guarantee your program runs at midnight, add a single flag to the config file to specify an offset function to use. You'd realistically only need three, one for the screwed up dates the US uses for changing to/from daylight saving time, one for the EU's summer time, and one for no change. 10 lines of code each.
The problem is determining when midnite is.
Seems to me that the real problem is determining how to spell midnight. 8)
Give a man a match, you keep him warm for an evening.
Light him on fire, he's warm for the rest of his life
This problem was solved by NQS (Network Queueing System) a long time ago. They have a date parsing routine that knows about timezones. You can either use NQS itself, or rip the date parser out of it. In any case, it allows you to specify, literally, "midnight EDT" as a time to run a job.
NQS code should be available on the net - the source was released by NASA a long time ago.