Python3關(guān)于current_app傳遞給子線程

在學(xué)習(xí)Flask的時候,《Flask Web開發(fā)》這本書中有一個異步發(fā)送email的例子,
其中用到了線程

from . import mail,create_app


def send_async_email(app,msg):
    with app.app_context():
        mail.send(msg)

def send_email(to,subject,template,**kwargs):
    msg = Message(current_app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,
                  sender=current_app.config['FLASKY_MAIL_SENDER'], recipients=[to])
    msg.body = render_template(template + '.txt', **kwargs)
    msg.html = render_template(template + '.txt', **kwargs)
    #with current_app.app_context():
    #    mail.send(msg)
    thr = Thread(target=send_async_email, args=(current_app, msg))
    thr.start()
    return thr

發(fā)送郵件總是提示錯誤
RuntimeError: Working outside of application context.
后來查找資料才知道是傳遞current_app的問題

current_app在 Flask是一個代理,如果你看 Flask源碼的話會發(fā)現(xiàn)其實它外部包裹的是這樣的:

def _find_app():
    top = _app_ctx_stack.top
    if top is None:
        raise RuntimeError(_app_ctx_err_msg)
    return top.app

...

current_app = LocalProxy(_find_app)

這個 LocalProxy就不展開講了霞揉,但是我可以告訴你這個LocalProxy的作用就是可以根據(jù)線程/協(xié)程返回對應(yīng)當前協(xié)程/線程的對象霹娄,也就是說
線程 A 往 LocalProxy 中塞入 A
線程 B 往 LocalProxy 中塞入 B
無論在是什么地方,線程 A 永遠取到得是 A旺聚,線程 B 取到得永遠是 B

這就是在 Flask中可以在代碼中直接使用 request、current_app這樣的變量的底層原因眶蕉。
所以砰粹,因為這里開了一個新線程,如果你不傳真實對象過去造挽,那么你在線程里面使用 current_app將獲取不到對象碱璃,因為他沒有 flask 上下文。

獲取真實對象Flask提供了一個方法:
_get_current_object()
官方文檔是這樣解釋:

Return the current object. This is useful if you want the real object behind the proxy at a time for performance reasons or because you want to pass the object into a different context.

修改send_email函數(shù)后代碼如下:

def send_email(to,subject,template,**kwargs):
    msg = Message(current_app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,
                  sender=current_app.config['FLASKY_MAIL_SENDER'], recipients=[to])
    msg.body = render_template(template + '.txt', **kwargs)
    msg.html = render_template(template + '.txt', **kwargs)
    #with current_app.app_context():
    #    mail.send(msg)
    #current_app只是一個代理獲取而已,傳遞給其它子線程獲取到的依然是子線程的上下文
    # 必須_get_current_object線獲取到原始對象再傳遞過去
    app = current_app._get_current_object()
    thr = Thread(target=send_async_email, args=(app, msg))
    thr.start()
    return thr

這樣就能異步發(fā)送郵件成功了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饭入,一起剝皮案震驚了整個濱河市嵌器,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谐丢,老刑警劉巖爽航,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乾忱,居然都是意外死亡讥珍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門窄瘟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衷佃,“玉大人,你說我怎么就攤上這事蹄葱∈弦澹” “怎么了锄列?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惯悠。 經(jīng)常有香客問我邻邮,道長,這世上最難降的妖魔是什么吮螺? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任饶囚,我火速辦了婚禮,結(jié)果婚禮上鸠补,老公的妹妹穿的比我還像新娘萝风。我一直安慰自己,他們只是感情好紫岩,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布规惰。 她就那樣靜靜地躺著,像睡著了一般泉蝌。 火紅的嫁衣襯著肌膚如雪歇万。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天勋陪,我揣著相機與錄音贪磺,去河邊找鬼。 笑死诅愚,一個胖子當著我的面吹牛寒锚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播违孝,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼刹前,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了雌桑?” 一聲冷哼從身側(cè)響起喇喉,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疹味,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年过咬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片制妄。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泵三,靈堂內(nèi)的尸體忽然破棺而出耕捞,到底是詐尸還是另有隱情衔掸,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布俺抽,位于F島的核電站敞映,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏磷斧。R本人自食惡果不足惜振愿,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弛饭。 院中可真熱鬧冕末,春花似錦、人聲如沸侣颂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽憔晒。三九已至藻肄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拒担,已是汗流浹背嘹屯。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留从撼,地道東北人州弟。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像谋逻,于是被迫代替她去往敵國和親呆馁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 22年12月更新:個人網(wǎng)站關(guān)停毁兆,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,165評論 22 257
  • 本篇文章是基于谷歌有關(guān)Graphic的一篇概覽文章的翻譯:http://source.android.com/de...
    lee_3do閱讀 7,109評論 2 21
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理浙滤,服務(wù)發(fā)現(xiàn),斷路器气堕,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • cookie篇 cookie是客戶端本地存儲的一種方式纺腊,常見的客戶端本地存儲的方式還有:session stora...
    TheoLin閱讀 195評論 0 1
  • 失城 ——寫給LXX 慢慢的你把生活過成了老照片 路人甲乙都不能看出里面的浩劫 故事的梗概懸浮在你燃起的香煙上 浮...
    蔥蔥_閱讀 331評論 10 12