5

How would you be able to move to the next iteration of a for loop if a given iteration takes more than a certain amount of time? The code should look something like this.

for i in range(0, max_iterations):
       timer function
       call to api

The timer function will serve the purpose of forcing the for loop to continue onto the next iteration if the api has not finished. It should work in 120 seconds for that iteration. How would the timer function be written? Thank you in advance!

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
Laura Holewa
  • 121
  • 1
  • 1
  • 9
  • Do any of the answers here help? http://stackoverflow.com/questions/492519/timeout-on-a-function-call – PM 2Ring Mar 21 '17 at 03:04
  • 1
    I don't know how time.sleep(secs) would be useful in this case. If I put time.sleep before the api call the program will just wait to execute the api call. I do not have the option of putting time.sleep inside the api call. – Laura Holewa Mar 21 '17 at 03:06
  • Which OS? There are fairly simple ways to do this on Unix / Linux. Is Python 3 an option? – PM 2Ring Mar 21 '17 at 03:08
  • Indeed. `time.sleep` is not useful here. Some of those linked answers just use sleep to simulate a function / API call that takes a long time. – PM 2Ring Mar 21 '17 at 03:09
  • I'm working on a linux system. – Laura Holewa Mar 21 '17 at 03:10
  • Python3 is not an option. – Laura Holewa Mar 21 '17 at 03:11
  • OK. But since you're on Linux you can use `signal`, as shown in that accepted answer. – PM 2Ring Mar 21 '17 at 03:15
  • However, there is a possibility that the API you're using may not work well with signal. In that case you will need to use `threading` or `multiprocessing`. – PM 2Ring Mar 21 '17 at 03:20
  • The "accepted" answer disappeared. :( Also @PM2Ring, do you have any advice about how to use threading or multiprocessing in this case? – Laura Holewa Mar 21 '17 at 07:22
  • 1
    What do you mean disappeared? I can still see [piro's accepted answer](http://stackoverflow.com/a/494273/4014959) However, [ATOzTOA's answer](http://stackoverflow.com/a/14924210/4014959) may work better for you. – PM 2Ring Mar 21 '17 at 08:02
  • Can you tell us more about the API you're using. That may help people write more specific answers. Without more details it's hard to do more than what's already in those answers I linked before. – PM 2Ring Mar 21 '17 at 08:03
  • I can't see any answers to this question as I could before, only comments. But thank you for including the links to those accepted answers. I am using the Yandex Translate API and sometimes when it can't translate a website it seems to just go on trying forever. – Laura Holewa Mar 21 '17 at 09:46
  • 1
    Jeremy Farrell posted an answer here, which told you to use `time.sleep` to do the timeout. But then he realised that he'd misunderstood your question, and changed his answer to link you to some info you may find useful. But then he deleted his revised answer. I'll repost Jeremy's links in the next comment. – PM 2Ring Mar 21 '17 at 10:08
  • 1
    Jeremy said: One way to solve this is to use threading. For a tutorial on using threading with events see [A basic example of threads synchronization in Python](http://zulko.github.io/blog/2013/09/19/a-basic-example-of-threads-synchronization-in-python/). The general idea is to run a your call on a separate thread, checking for results every so often. For another alternative see this answer: http://stackoverflow.com/a/14924210/2109767. – PM 2Ring Mar 21 '17 at 10:09
  • Thank you @PM2Ring, you have been very helpful to me. For now, I found this answer that seems like it will work. (I will have to test when I have not exceeded my Yandex translation limit for the day.) http://stackoverflow.com/questions/25027122/break-the-function-after-certain-time – Laura Holewa Mar 21 '17 at 10:51
  • Possible duplicate of [break the function after certain time](https://stackoverflow.com/questions/25027122/break-the-function-after-certain-time) – Vineet Jain Oct 21 '17 at 11:52

1 Answers1

0

This is only truly possible with a non-blocking API call or an API call with a timeout. For example, if you are using the socket library, you could use socket.setblocking(0)to make the socket API calls non-blocking.

In your case, you have said you are using the Yandex API. This appears to be JSON over https, so you may wish to try urllib2.urlopen(). This method accepts a timeout. This is even easier than using a non-blocking call as urlopen() will simply give up and return an error after the timeout has expired.

Using threads as suggested in some of the comments will give you a partial solution. Since there is no ability to stop a thread started with the threading module, all of the API calls you initiate that do not complete will stay in a blocked state for the life of the python interpreter and those threads will never exit.

If you do use the threading module to solve this problem, you should make all of the threads that run API calls daemon threads thread.setDaemon(True) so that when your main thread exits, the interpreter stops. Otherwise the interpreter will not exit until all of the API calls have completed and returned.

J. Beattie
  • 183
  • 1
  • 7