![](/img/trans.png)
[英]Getting ServerNotFoundError when using gevent/greenlets with requests
[英]Error when using twisted and greenlets
我正在嘗試將Twisted與greenlet一起使用,因此我可以在不使用inlineCallbacks的情況下以twisted形式編寫同步外觀的代碼。
這是我的代碼:
import time, functools
from twisted.internet import reactor, threads
from twisted.internet.defer import Deferred
from functools import wraps
import greenlet
def make_async(func):
@wraps(func)
def wrapper(*pos, **kwds):
d = Deferred()
def greenlet_func():
try:
rc = func(*pos, **kwds)
d.callback(rc)
except Exception, ex:
print ex
d.errback(ex)
g = greenlet.greenlet(greenlet_func)
g.switch()
return d
return wrapper
def sleep(t):
print "sleep(): greenelet:", greenlet.getcurrent()
g = greenlet.getcurrent()
reactor.callLater(t, g.switch)
g.parent.switch()
def wait_one(d):
print "wait_one(): greenelet:", greenlet.getcurrent()
g = greenlet.getcurrent()
active = True
def callback(result):
if not active:
g.switch(result)
else:
reactor.callLater(0, g.switch, result)
def errback(failure):
if not active:
g.throw(failure)
else:
reactor.callLater(0, g.throw, failure)
d.addCallback(callback)
d.addErrback(errback)
active = False
rc = g.parent.switch()
return rc
@make_async
def inner():
print "inner(): greenelet:", greenlet.getcurrent()
import random, time
interval = random.random()
print "Sleeping for %s seconds..." % interval
sleep(interval)
print "done"
return interval
@make_async
def outer():
print "outer(): greenelet:", greenlet.getcurrent()
print wait_one(inner())
print "Here"
reactor.callLater(0, outer)
reactor.run()
有五個主要部分:
運行此代碼時,我得到以下輸出(請注意最后兩行的錯誤):
outer(): greenelet: <greenlet.greenlet object at 0xb729cc5c>
inner(): greenelet: <greenlet.greenlet object at 0xb729ce3c>
Sleeping for 0.545666723422 seconds...
sleep(): greenelet: <greenlet.greenlet object at 0xb729ce3c>
wait_one(): greenelet: <greenlet.greenlet object at 0xb729cc5c>
done
0.545666723422
Here
Exception twisted.python.failure.Failure: <twisted.python.failure.Failure <class 'greenlet.GreenletExit'>> in <greenlet.greenlet object at 0xb729ce3c> ignored
GreenletExit did not kill <greenlet.greenlet object at 0xb729ce3c>
經過一些研究,我發現:
我在調試它時遇到了麻煩,因為我無法訪問GreenletExit
或twisted.python.failure.Failure
異常以獲取其堆棧跟蹤。
有誰知道我在做什么錯,或者我如何調試正在拋出的異常?
另一個數據點:如果我砍下wait_one()以便立即返回(並且不對延遲傳遞的任何內容進行注冊),則錯誤會消失。 : - /
像這樣在wait_one
重寫錯誤回調:
def errback(failure):
## new code
if g.dead:
return
##
if not active:
g.throw(failure)
else:
reactor.callLater(0, g.throw, failure)
如果greenlet已死(運行結束),則沒有任何異常拋出。
mguijarr的答案解決了該問題,但我想寫下我如何陷入這種情況。
我有三個Greenlet:
睡眠完成后,{main}切換到{inner},后者切換到{outer}。 然后,外層返回並在{inner}中引發GreenletExit。 這傳播回扭曲。 它看到從callback()引發了異常,因此調用了errback()。 這試圖將異常拋出到{outer}中(已經退出),我遇到了錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.