2

I want to send two asynchronous requests using grequests.send with a short but exact delay (say 20 ms) between them. I only want to handle the responses after both requests have been sent.

Putting a time.sleep between the two sends doesn't work because sleep yields to the response handler for request 1 before request 2 has been sent, so request 2 is sent late.

grequests.send(req1, grequests.Pool(1))
time.sleep(delay)
grequests.send(req2, grequests.Pool(1)) # Request is sent late

How can I ensure the whole block above is run atomically to ensure as close as possible to the expected wait time between requests, without a busy wait?

akxlr
  • 1,142
  • 9
  • 23
  • I don't think trying to pause a process for an _exact_ amount of time on a multitasking OS is feasible; your process is at the mercy of the OS's scheduler, which may resume your process later than the requested wait time. – Colonel Thirty Two Nov 12 '15 at 01:59
  • @ColonelThirtyTwo True. I guess what I mean is 'as exact as possible'. I can tolerate it being wrong by a few ms. – akxlr Nov 12 '15 at 02:12
  • You can do a "busy wait loop" and watch a clock until the amount of time has passed. – martineau Nov 12 '15 at 02:13

1 Answers1

0

The most elegant way to do this is to not monkey patch time . So do this:

from gevent import monkey
monkey.patch_all(time=False)

Then when you use time.sleep it will NOT yield.

If you use gevent.sleep, it will still sleep and yield, should you need that functionality as well.

Be aware that if you use other libraries that use time.sleep, they will not yield at that point. But it's rare, so should not be an issue.

DevShark
  • 8,558
  • 9
  • 32
  • 56