Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • sleep command - milliseconds upper limit

    I would like to pause a stata command for 24 hours due to some externally imposed restriction on coding data (FYI opencagegeo which limits the amount of geocoded observations per day).
    I thererfore tried to use the sleep command to re-start the command automatically after the 24 hours:
    Code:
     sleep 86400000
    corresponding to the number of milliseconds in a day. However, the command did not pause at all. It does work for a lower value instead, like 10000 (i.e. 10 seconds). For instance
    Code:
    forvalues i = 1/2 {
        di `i'
        sleep 86400000
    }
    does not work and displays without pausing. But
    Code:
    forvalues i = 1/2 {
        di `i'
        sleep 10000
    }
    works. Hence, I am guessing there is an upper limit to the number of milliseconds but this is not indicated in the help. Does anyone know?
    Regards,
    Mario

  • #2
    I am not sure about the upper end of sleep. An alternative would be to take the current date and time, add 24 hours and then write a while loop which pauses Stata for say a minute until the current time is smaller than the projected end time. An example would be:

    Code:
    local now = clock("`c(current_date)' `c(current_time)'","DMYhms")
    
    local endtime = `now' + 1000*60*60*24
    
    display "Loop starts at " %tcDDmonCCYY_HH:MM:SS `starttime'
    display "Loop finishes at " %tcDDmonCCYY_HH:MM:SS  `endtime'
    
    while `now' < `endtime' {
        display "wait for one more minute (`c(current_date)' `c(current_time)')..."
        sleep 60000
        local now = clock("`c(current_date)' `c(current_time)'","DMYhms")
    }
    This might be a bit longer solution than just putting a time to wait into a line.

    Comment


    • #3
      Since you are wanting to pause execution for about a day between runs, might it be easier to schedule this as a daily task in your operating system's environment?

      Comment


      • #4
        We can answer this question approximately with an easy experiment. Note that the answer may depend on the operating system you are running on. On mine, the answer seems to be somewhere between 2,147,000 and 2,148,000 milliseconds.
        Code:
        cls
        set more off
        about
        local tosleep 10000000
        local delta    1000000
        while `delta' >=  1000 {
            display "trying " %12.0fc `tosleep'
            capture sleep `tosleep' // hit break if it doesn't return immediately
            if _rc>0 {
                display "that ran!"
                local tosleep = `tosleep' + `delta'
                local delta = `delta' / 10
                }
            else {
                local tosleep = `tosleep' - `delta'
                }
            }
        Code:
        . set more off
        
        . about
        
        Stata/SE 16.0 for Mac (64-bit Intel)
        Revision 11 Dec 2019
         [stuff omitted]
        
        . local tosleep 10000000
        
        . local delta    1000000
        
        . while `delta' >=  1000 {
          2.     display "trying " %12.0fc `tosleep'
          3.     capture sleep `tosleep' // hit break if it doesn't return immediately
          4.         if _rc>0 {
          5.             display "that ran!"
          6.             local tosleep = `tosleep' + `delta'
          7.                 local delta = `delta' / 10
          8.                 }
          9.         else {
         10.             local tosleep = `tosleep' - `delta'
         11.                 }
         12.         }
        trying   10,000,000
        trying    9,000,000
        trying    8,000,000
        trying    7,000,000
        trying    6,000,000
        trying    5,000,000
        trying    4,000,000
        trying    3,000,000
        trying    2,000,000
        that ran!
        trying    3,000,000
        trying    2,900,000
        trying    2,800,000
        trying    2,700,000
        trying    2,600,000
        trying    2,500,000
        trying    2,400,000
        trying    2,300,000
        trying    2,200,000
        trying    2,100,000
        that ran!
        trying    2,200,000
        trying    2,190,000
        trying    2,180,000
        trying    2,170,000
        trying    2,160,000
        trying    2,150,000
        trying    2,140,000
        that ran!
        trying    2,150,000
        trying    2,149,000
        trying    2,148,000
        trying    2,147,000
        that ran!
        
        .

        Comment


        • #5
          Thanks William Lisowski, that's a smart way of figuring the limit! I am still unimpressed by Stata though. First of all why such a low limit and second, whatever the reason, the limit should be clearly indicated in the help.
          Also thanks to JanDitzen for the idea. I went for a loop based on my initial code
          Code:
          forvalues i = 1/1440{ // number of minutes in a day
              di `i'
              sleep 60000 //  one minute
          }
          which is shorter but less elegant than your solution.
          Leonardo Guizzetti I am not sure how to implement your idea. I guess you are thinking of a script that calls a Stata do file every 24 hours. Do you have a reference for this? I am on OSX. Thanks to all!
          Mario

          Comment


          • #6
            Hi Mario, I don't use Mac, but there must be an equivalent to Windows job scheduler and Linux's cron scheduler. You might have better luck searching online if that is of interest.

            Comment


            • #7
              First of all why such a low limit
              At the library level, macOS provides the usleep() function that programs can use to sleep for a given number of microseconds. When we convert 2,147,000 milliseconds to microseconds and take the base2 log, we get a number just below 31. So the cutoff for correct functioning is likely 231-1 = 2,147,483,647 microseconds, or to Stata 2,147,483 milliseconds - between 35 and 36 minutes. And an 8-byte integer is 31 bits in length (excluding the sign bit), so there you have it.

              I believe the model StataCorp has for the sleep command is to handle synchronization of immediate activities, like giving the operating system the time to complete the writing of a just-closed dataset to a network drive before trying to re-open that dataset for reading. As a consequence they chose the usleep() function to allow a finer control than the sleep() function, which works in one-second increments. I don't think StataCorp anticipates Stata being used as a job scheduler - if that's what is needed, that's usually better done through other techniques. But "the law of the instrument" tells us if my tool is a hammer, then to me the whole world is a nail.

              I'd hoped to recommend the workaround of using the operating system's sleep command, which is calibrated in seconds. But when I tried
              Code:
              shell sleep 2148
              not only did it run, but attempting to interrupt it with Stata's break button failed, and the only way to stop the process seems to be to force quit Stata.

              second, whatever the reason, the limit should be clearly indicated in the help.
              We all have our favorite additions that we'd like to see included in the help. My own is for more comprehensive documentation of the regular expression engine used in the unicode regular expression functions, where by "more comprehensive" I mean at least an identification of the engine used, and more generously a link to documentation of the syntax.

              In this, as in much of life, I find I am doomed to disappointment.

              Comment


              • #8
                Thanks William Lisowski, I now understand the reason for the limit.
                In this, as in much of life, I find I am doomed to disappointment.
                LOL, I share the feeling!

                Comment

                Working...
                X