9

次のコードは、200 ミリ秒ごとに要求を送信し、応答が来るたびに非同期で処理する必要があります。

HTTP 経由では期待どおりに動作します。リクエストは 200 ミリ秒ごとに送信され、レスポンスが到着するたびにレスポンス コールバックが個別に呼び出されます。ただし、HTTPS では、応答が到着するたびに要求が大幅に遅延します (応答ハンドラーが機能しない場合でも)。応答コールバックは、要求ごとに 2 回呼び出され、1 回は長さゼロの応答で呼び出されるようです (編集: これはリダイレクトのためであり、ブロッキングの問題とは無関係のようです、Padraic に感謝します)。

HTTPS を介したこのブロック動作の原因は何ですか? (www.bbc.co.uk地理的に私から離れた例にすぎませんが、テストしたすべてのサーバーで発生します)。

grequests_test.py

import time
import sys
import grequests
import gevent

def cb(res, **kwargs):
    print("**** Response", time.time(), len(res.text))

for i in range(10):
    unsent = grequests.get(sys.argv[1], hooks={'response': cb})
    print("Request", time.time())
    grequests.send(unsent, grequests.Pool(1))
    gevent.sleep(0.2)
gevent.sleep(5)

$ ipython2 grequests_test.py 'http://www.bbc.co.uk'(期待される結果)

('Request', 1459050191.499266)
('Request', 1459050191.701466)
('Request', 1459050191.903223)
('Request', 1459050192.10403)
('Request', 1459050192.305626)
('**** Response', 1459050192.099185, 179643)
('Request', 1459050192.506476)
('**** Response', 1459050192.307869, 179643)
('Request', 1459050192.707745)
('**** Response', 1459050192.484711, 179643)
('Request', 1459050192.909376)
('**** Response', 1459050192.696583, 179643)
('Request', 1459050193.110528)
('**** Response', 1459050192.870476, 179643)
('Request', 1459050193.311601)
('**** Response', 1459050193.071679, 179639)
('**** Response', 1459050193.313615, 179680)
('**** Response', 1459050193.4959, 179643)
('**** Response', 1459050193.687054, 179680)
('**** Response', 1459050193.902827, 179639)

ipython2 grequests_test.py 'https://www.bbc.co.uk'(リクエストは遅れて送信されます)

('Request', 1459050203.24336)
('Request', 1459050203.44473)
('**** Response', 1459050204.423302, 0)
('Request', 1459050204.424748) <------------- THIS REQUEST TIME IS LATE
('**** Response', 1459050205.294426, 0)
('Request', 1459050205.296722)
('Request', 1459050205.497924)
('**** Response', 1459050206.456572, 0)
('Request', 1459050206.457875)
('**** Response', 1459050207.363188, 0)
('**** Response', 1459050208.247189, 0)
('Request', 1459050208.249579)
('**** Response', 1459050208.250645, 179643)
('**** Response', 1459050208.253638, 179643)
('Request', 1459050208.451083)
('**** Response', 1459050209.426556, 0)
('Request', 1459050209.428032)
('**** Response', 1459050209.428929, 179643)
('**** Response', 1459050210.331425, 0)
('**** Response', 1459050211.247793, 0)
('Request', 1459050211.251574)
('**** Response', 1459050211.252321, 179643)
('**** Response', 1459050211.25519, 179680)
('**** Response', 1459050212.397186, 0)
('**** Response', 1459050213.299109, 0)
('**** Response', 1459050213.588854, 179588)
('**** Response', 1459050213.590434, 179643)
('**** Response', 1459050213.593731, 179643)
('**** Response', 1459050213.90507, 179643)
('**** Response', 1459050213.909386, 179643)

最初の応答は、次の要求が送信されるはずだったのに送信されてからかなり後に到着したように見えることに注意してください。最初の応答が到着する前に、スリープが返されず、次の要求が送信されなかったのはなぜですか?

4

2 に答える 2

1

grequests の現在の反復には、以下が含まれます。

from gevent import monkey as curious_george
curious_george.patch_all(thread=False, select=False)

問題のある部分はselect=False、これを削除するか、手動で呼び出すことmonkey.patch_select()で問題が解決することです。これに他の副作用があるかどうかはわかりません。

于 2016-03-31T09:54:51.763 に答える