我刚创建了一个脚本,该脚本触发特定API的报告,然后将其加载到我的数据库中。 我已经构建了一些可行的东西,但我想知道是否有一些更“精确”或高效的东西,而不需要让我的脚本循环遍及。
我目前的脚本如下:
import time
retry=1
trigger_report(report_id)
while report_id.status() != 'Complete':
time.sleep(retry * 1.3)
retry =+ 1
load_report(report_id)
修改
API不提供任何等待完成方法,它最多的是返回作业状态的端点。 它是一个SOAP API。
答案 0 :(得分:0)
虽然这篇文章与你说的不再有任何关联,但它是一个肥皂API。但是我把工作放进去了,所以无论如何我都会发布它。 :)
回答你的问题。我没有看到比轮询更有效的方法(也就是一遍又一遍地循环)
有多种方法可以做到。
第一种方法是实现在任务完成时触发的某种回调。它看起来像这样:
bsxfun
如您所见,操作完成后将立即打印消息“import time
def expensive_operation(callback):
time.sleep(20)
callback(6)
expensive_operation(lambda x:print("Done", x))
”。
您可以使用Future-objects重写此内容。
Done 6
由于这看起来很复杂,因此有一些高级函数可以为您实现线程调度。
from concurrent.futures import Future
import threading
import time
def expensive_operation_impl():
time.sleep(20)
return 6
def expensive_operation():
fut = Future()
def _op_wrapper():
try:
result = expensive_operation_impl()
except Exception as e:
fut.set_exception(e)
else:
fut.set_result(result)
thr = threading.Thread(target=_op_wrapper)
thr.start()
return fut
future = expensive_operation()
print(future.result()) # Will block until the operation is done.
答案 1 :(得分:-3)
而是使用事件,而不是轮询。如何在Python中实现事件有很多选项。有一个讨论here already on stack overflow。
这是一个使用zope.event和事件处理程序
的合成示例import zope.event
import time
def trigger_report(report_id):
#do expensive operation like SOAP call
print('start expensive operation')
time.sleep(5)
print('5 seconds later...')
zope.event.notify('Success') #triggers 'replied' function
def replied(event): #this is the event handler
#event contains the text 'Success'
print(event)
def calling_function():
zope.event.subscribers.append(replied)
trigger_report('1')
但接受答案的期货也很整洁。取决于你的船漂浮的东西。