- responses.start()
- rex_a.async_get(url_a)
- rex_b.async_get(url_b)
- rex_a.result()
- requests.get(url_a)
- responses triggers callback
- pytest_vts.vts.record._callback()
- responses.stop()
- requests.get(url_a)
- greenlet switches to gevent main loop gevent main loop picks another greenlet to run. Let's assume resumes with 1.
- rex_b.result() 3. requests.get(url_a) 3. because of greenlet 2. stopping responses this requests goes through 3. greenlet switches to gevent main loop gevent main loop picks another greenlet to run. Let's assume resumes 2.
- requests.get(url_a) finishes
- recorded to the cassette track
- responses.start()
- greenlet ends and switches to gevent main loop gevent main loop picks another greenlet to run. Let's assume resumes 3. 3. requests.get(url_b) finishes 3. since it wasn't executed in responses callback registered by vts => no cassette 3. greenlet ends and switches to gevent main loop
The above example uses greenlets, but the same is valid for threads, maybe even worse since threads are scheduled by OS and can switch anywhere not only in blocking operations.
Instead of using requests to make the http call which should bypass responses, use something else (e.g. urllib3) which is not patched by responses. That way we can avoid stop-ing() start-ing() responses.