Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I was wondering a good way to do something...

The last day of every month I have to stay up all night to shut the website down at midnight PST, or one second before, so no new orders make it on the new month until I reset everything...

After I shut down the website for our members, our other programmer has to run some utilities on the databases to make sure they have no errors in them. This can take as little as 2 hours or as much as 6 hours.

So I made a system variable in a database that his system (in PHP) can update when it is done: update pagevars set value = "ready" where name = eom_process

So I want to automate this so I don't have to be right there to do it.

So my question is this.
Could I start my script when it is supposed to, have it shut down the website then do something like this without killing the server memory or resources:
#shut off website... $_sleepTime = (60 * 5); until($dbh->selectrow_array(qq{select `value` from `pagevars` where `n +ame` = "eom_process"}) eq "ready") { sleep($_sleepTime); } # once ready then it will continue the functions until completed then +turn the website back on
I have not really utilized sleep before so I'm not sure if it would work properly.

Do you know if that would kill the system memory or create anything else to go wrong?

Or do you know a better way to do it?

Thanks,
Richard

Replies are listed 'Best First'.
Re: automating a task
by NetWallah (Canon) on May 31, 2009 at 19:49 UTC
    ....or create anything else to go wrong?

    If I were writing that, I would allow for the database going off-line while the program sleeps.

    This is important if you are doing maintenance work. $dbh may no longer be valid when you wake up. I would put some code to try to re-connect (with sleep/retry) if the current connection is invalid.

    I would also add some escape route - reporting the catastrophe, in case of "repeated failure" for an "extended period", for some definition of those terms.

         Potentia vobiscum ! (Si hoc legere scis nimium eruditionis habes)

      Ok, so this would suffice:

      #shut off website... my $_sleepTime = (60 * 5); my $_notifyTime = time() + (60 * 60); my $_maxTime = time() + (60 * 60 * 6); until($dbh->selectrow_array(qq{select `value` from `pagevars` where `n +ame` = "eom_process"}) eq "ready") { $dbh->disconnect(); sleep($_sleepTime); $dbh = RWC::Sess::connect(); if(time() >= $_notifyTime) { # Send an email notifying of still not running... $_notifyTime = time() + (60 * 60);# Reset timer } if(time() >= $_maxTime) { # Send notice of final disconnection and exiting # to manually fix... send this notice to my cell # phone to alarm me # Disconnect from database.... if connected if($dbh) { $dbh->disconnect(); } exit; } }

      that makes logical sense... so while it is sleeping it does not use any memory right? what if it does take all that time everytime it starts again does it keep building upon the memory it had and then get larger and larger? or does the disconnecting from the database reduce the memory on the fly, even before perl is exited?

      thanks again,
      Richard

        ...so while it is sleeping it does not use any memory right?

        No, not right: it still reserves whatever memory it had allocated when the sleep starts at line 7 (which includes a small amount of memory required for the countdown tracking) -- and it still uses a few CPU cycles to do the tracking.

        what if it does take all that time everytime it starts again does it keep building upon the memory it had and then get larger and larger?

        There's no obvious (to me) reason for the memory useage to grow when the sleep time expires. However, you're disconnecting from the database before the sleep, so you'll need someone with a better handle on garbage collection and memory release to get a knowledgeable reply. Note, though, that "starts again" is perhaps better phrased "resumes." sleep does not force reinitialization of anything, except as forced to do so by your code.

        ...reduce the memory on the fly, even before perl is exited?

        Likewise, heed what wiser heads say about this, but my understanding is that that's not likely.

Re: automating a task
by CountZero (Bishop) on Jun 01, 2009 at 07:31 UTC
    I would take another approach.

    In the code of your dynamic website, I would add a check to the "eom_process" field in your database. If that field is not "ready", your script serves a static page "This site is now being maintained -- come back later" for your members. Meanwhile your colleague can do all maintenance required and when he is ready he sets the "eom_process" field to "ready" again and your members have access.

    All you have to do is change that field to not "ready" when necessary. It would not take too much effort to write a small script to have a cron job do that for you.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I like this sort of idea. If you are shutting down the website, then a phased process is good. (1)Stop accepting new connections ("we are down for monthly maintenance at time X, expected time-up is time Y"). (2)For users logged in and doing things, try to find some "stopping point" so that their connection can be closed gracefully and their transactions wind up in a consistent state to the best of your program's knowledge. You will have to decide what to do if you can't get the users to log off themselves.

      The DB maintenance program that is gonna run may change things to the extent that any pending changes that you might be aware of won't work right. Anyway get the DB to what you figure is a consistent state.

      Rather than you shutting down at a specific time, you could have some I/F so that this maint program requests a shutdown, and when it is done, you reply back that you are shut down. When it is finished, it tells you that you can come back online. You want to come back up ASAP when it is finished. This I/F could be pretty simple with some file flags and perhaps some cell phone message if things stay down for too long.

      Anyway the shutdown from your end may take a variable amount of time. And obviously what this other thing does takes a variable amount of time.

Re: automating a task
by marcussen (Pilgrim) on Jun 01, 2009 at 07:21 UTC

    Crontab is the obvious choice.
    I'm a little curious why you need to shut down the site database at all. If you use dates with your orders you should be able to limit the orders by date, thus any order placed after your "magic" time limit, is excluded from the selection...

    If you absolutely must stop entries into the database, then perhaps you should simply hotswap to standby database and still avoid the downtime. I don't have an in depth understanding of your model, but I suspect there is room for improvement.

    Confucius says kill mosquito unless cannon