gpt4 book ai didi

python - 我可以将 webapp2.RequestHandler 请求异步复制到不同的 url 吗?

转载 作者:行者123 更新时间:2023-11-28 18:29:14 24 4
gpt4 key购买 nike

对于一定比例的生产流量,我想将收到的请求复制到我的应用程序的不同版本。这需要异步发生,所以我不会加倍为客户提供服务。

这样做的原因是我可以比较生产版本和生产候选版本生成的响应。如果它们的结果适当相似,我可以确信新版本没有破坏任何东西。 (如果我对应用程序进行了功能更改,我会从该比较中过滤掉响应的必要部分。)

所以我正在寻找等同于:

class Foo(webapp2.RequestHandler):
def post(self):
handle = make_async_call_to('http://other_service_endpoint.com/', self.request)

# process the user's request in the usual way

test_response = handle.get_response()

# compare the locally-prepared response and the remote one, and log
# the diffs

# return the locally-prepared response to the caller

更新google.appengine.api.urlfetch 被建议作为我的问题的潜在解决方案,但它是同步的 在 dev_appserver 中,尽管它的行为符合我在生产中想要的方式(请求直到 get_response 才发出() 被调用,它会阻塞)。 :

    start_time = time.time()
rpcs = []

print 'creating rpcs:'
for _ in xrange(3):
rpcs.append(urlfetch.create_rpc())
print time.time() - start_time

print 'making fetch calls:'
for rpc in rpcs:
urlfetch.make_fetch_call(rpc, 'http://httpbin.org/delay/3')
print time.time() - start_time

print 'getting results:'
for rpc in rpcs:
rpc.get_result()
print time.time() - start_time


creating rpcs:
9.51290130615e-05
0.000154972076416
0.000189065933228
making fetch calls:
0.00029993057251
0.000356912612915
0.000473976135254
getting results:
3.15417003632
6.31326603889
9.46627306938

UPDATE2

因此,在尝试了一些其他选项之后,我找到了一种发出完全非阻塞请求的方法:

start_time = time.time()
rpcs = []

logging.info('creating rpcs:')
for i in xrange(10):
rpc = urlfetch.create_rpc(deadline=30.0)
url = 'http://httpbin.org/delay/{}'.format(i)
urlfetch.make_fetch_call(rpc, url)
rpc.callback = create_callback(rpc, url)
rpcs.append(rpc)
logging.info(time.time() - start_time)

logging.info('getting results:')
while rpcs:
rpc = apiproxy_stub_map.UserRPC.wait_any(rpcs)
rpcs.remove(rpc)
logging.info(time.time() - start_time)

...但需要注意的重要一点是,urllib 中的所有异步获取选项都无法在 dev_appserver 中工作。发现这一点后,我回去尝试@DanCornilescu 的解决方案并发现它仅在生产中正常工作,但在 dev_appserver 中不正常。

最佳答案

URL Fetch 服务支持异步请求。来自 Issuing an asynchronous request :

HTTP(S) requests are synchronous by default. To issue an asynchronous request, your application must:

  1. Create a new RPC object using urlfetch.create_rpc(). This object represents your asynchronous call in subsequent method calls.
  2. Call urlfetch.make_fetch_call() to make the request. This method takes your RPC object and the request target's URL as parameters.
  3. Call the RPC object's get_result() method. This method returns the result object if the request is successful, and raises an exception if an error occurred during the request.

The following snippets demonstrate how to make a basic asynchronous request from a Python application. First, import the urlfetch library from the App Engine SDK:

from google.appengine.api import urlfetch

Next, use urlfetch to make the asynchronous request:

rpc = urlfetch.create_rpc()
urlfetch.make_fetch_call(rpc, "http://www.google.com/")

# ... do other things ...
try:
result = rpc.get_result()
if result.status_code == 200:
text = result.content
self.response.write(text)
else:
self.response.status_code = result.status_code
logging.error("Error making RPC request")
except urlfetch.DownloadError:
logging.error("Error fetching URL0")

注意:根据问题更新中提到的 Sniggerfardimungus 实验,异步调用可能无法在开发服务器上按预期工作 - 被序列化而不是并发,但它们在 GAE 上部署时会这样做。就我个人而言,我还没有使用异步调用,所以我真的不能说。

如果意图不是阻止根本等待来自生产候选应用程序的响应,您可以将原始请求的副本和生产准备好的响应推送到任务队列,然后回答原始请求 - 延迟可忽略不计(将任务排队)。

相应任务队列的处理程序将在原始请求的关键路径之外,使用原始请求的副本向登台应用发出请求(异步与否,从影响生产应用程序的响应时间),获取其响应并将其与生产准备的响应进行比较,记录增量等。这可以很好地包装在一个单独的模块中,以便对生产应用程序进行最小的更改并根据需要部署/删除。

关于python - 我可以将 webapp2.RequestHandler 请求异步复制到不同的 url 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38799566/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com