-1

I have this following code and am stuck in the while loop

I know there is a problem with the while datetime.datetime.now() < (datetime.datetime.now() + datetime.timedelta(minutes=wait_time)): line.

Can anyone help please ?

nodes_with_scanner = []
    wait_time = 60
    while datetime.datetime.now() < (datetime.datetime.now() + datetime.timedelta(minutes=wait_time)):
        nodes_with_scanner = get_nodes_with_scanner_in_dps(self.node_names, scanner_id, username=self.users[0].username)
        log.logger.debug("Number of pre-defined {0} scanners detected in DPS: {1}/{2}".format(scanner_type, len(nodes_with_scanner), len(self.node_names)))

        if state == "create":
            if len(self.node_names) == len(nodes_with_scanner):
                log.logger.debug("All {0} pre-defined scanners with id '{1}' have been successfully created in DPS for nodes '{2}'".format(scanner_type, scanner_id, ", ".join(self.node_names)))
                return
        elif state == "delete":
            if len(nodes_with_scanner) < 1:
                log.logger.debug("All {0} pre-defined scanners with id '{1}' have been successfully deleted in DPS for nodes '{2}'".format(scanner_type, scanner_id, ", ".join(self.node_names)))
                return
        log.logger.debug("Still waiting on some {0} pre-defined scanners to '{1}' in DPS; sleeping for 1 minute before next check".format(scanner_type, state))
        time.sleep(60)
Dante
  • 548
  • 1
  • 7
  • 19
  • 1
    Every single time you call it, `datetime.datetime.now()+datetime.timedelta(minutes=wait_time)` inches into the future. – NightShadeQueen Jul 21 '15 at 12:51
  • 1
    Also, do you happen to be using `datetime` anywhere else? Because, honestly, you could use `time.time()` here. – NightShadeQueen Jul 21 '15 at 12:52
  • 1
    You are stuck in while loop `datetime.datetime.now()` will always be less than `(datetime.datetime.now() + datetime.timedelta(minutes=wait_time))`. – Tanmaya Meher Jul 21 '15 at 12:55

2 Answers2

3

You are asking if the current time is smaller than the current time plus a delta. Of course that's going to be true each and every time, the future is always further away into the future.

Record a starting time once:

start = datetime.datetime.now()
while datetime.datetime.now() < start + datetime.timedelta(minutes=wait_time)):

If wait_time doesn't vary in the loop, store the end time (current time plus delta):

end = datetime.datetime.now() + datetime.timedelta(minutes=wait_time))
while datetime.datetime.now() < end:

It may be easier to just use time.time() here:

end = time.time() + 60 * wait_time
while time.time() < end:
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks so much for this. Can't believe I didn't notice this. Thanks again. – Dante Jul 22 '15 at 08:06
  • 1. `datetime.now()`-based solution may fail around DST transitions e.g., due to "fall back" in autumn in the northern hemisphere. See [Find if 24 hrs have passed between datetimes - Python](http://stackoverflow.com/q/26313520/4279) 2. `time.time()` may fail due to computer clock adjustments (jumps can be huge inside a VM). `time.monotonic()` could be used for some use-cases instead. – jfs Jul 22 '15 at 17:58
  • @J.F.Sebastian: yes, `time.monotonic()` would not fall pray to time adjustments, but is only available on Python 3. – Martijn Pieters Jul 22 '15 at 18:20
  • @MartijnPieters: You could call `utcnow()` on Python 2 too (instead of `now()`). It is worth mentioning even Python 3 only solution (I don't see [tag:python-2.7] tag on the question). You could call `GetTickCount64()`, `mach_absolute_time()`, [`clock_gettime(CLOCK_MONOTONIC_RAW)` via `ctypes` on Python 2 too](https://gist.github.com/zed/5073409). Or [use a backport that does it for you](https://github.com/gavinbeatty/python-monotonic-time/) – jfs Jul 22 '15 at 18:52
2

You use datetime.datetime.now() in your while loop, what means each iteration you check if the time now is lower then the time now + delta.

That logically wrong, because it will be True forever as the time now will be always lower than the time now plus delta.

You should change it to this:

time_to_start = datetime.datetime.now() 
while datetime.datetime.now() < (time_to_start + datetime.timedelta(minutes=wait_time)):
    print "do something"
omri_saadon
  • 10,193
  • 7
  • 33
  • 58