(回転)Twisted:第18部Deferreds全貌
概要
前のセクションでは,ジェネレータを用いて順序非同期コールバックを構築する新しい方法を学習した.
時には、しかし、私達は“並列”の1組の非同期の操作を実行する必要があります.Twistedは単一のスレッドのため、それは実際に同時に運行することはできませんが、私達は非同期I/Oを使って1組の任務の上でできるだけ速い仕事をしたいです.私達の詩のクライアントを例にして、それは複数のサーバーから同時に詩をダウンロードします.次から次へとではなく、Twistedを使って詩をダウンロードするすべての特徴です.
結果として、すべての詩クライアントは問題を解決する必要があります.どのようにして起動したすべての非同期操作が完了したことを知っていますか.クライアント7.0のような結果セットをリストにまとめることで 結果 成功した結果を収集する以外に、失敗に注意しなければならない.そうしないと、失敗はプログラムをデッドサイクルにし、仕事が必要だと思っている.
予想通り、Twistedにはこの問題を解決するための抽象層が含まれています.見てみましょう.
DeferredList
にある deferred-list/deferred-list-1.py で、次のコードを見つけることができます.
実行すると、次のような出力が得られます.
次の点に注意してください. 上記の例では、コールバックが追加されるとすぐに励起するので、 下を見て deferred-list/deferred-list-2.py:
次に、
次の点に注意してください.今回 の結果は同じリストですが、今回は要素が含まれています. この要素はメタグループで、2番目の値はリストにあります. リストに2つ追加しましょう
次のような出力が得られます.
現在
では、最終結果リストの要素の順序はどうですか?次のコード( deferred-list/deferred-list-4.py):
ここではd 2を励起してからd 1を励起し,構造パラメータの
出力リストの結果の順序と元の
リストの1つ以上が
ここで、d 1は正常な結果で励起され、d 2はエラーで励起される.
今回d 2に対応するメタグループが2番目の位置に1つ現れた 元のリストのすべてが 結果リストの各要素は、元のリストの対応する
では、転送されることについてお話ししましょう.
「Unhandled error in Deferred」メッセージは
しかしconsumeErrors=Trueを
クライアント8.0
詩歌クライアント8.0のリリースを取得しました!クライアント使用
君は クライアント7.0 の該当部分を比較する.
クライアント8.0ではpoem_は必要ありませんdoneコールバックとresultsリストです.逆に、getからtransformed_poemが返す
ディスカッション
ビジュアル化
図37:
とても簡単で、本当です.
にある :doc:`p19` ではさらにご紹介します
参考練習 読書 deferred-listの例を変更してオプションのコンストラクタパラメータを実現 使えます 修正クライアント8.0すべての詩がダウンロードされる前に任意の情報を印刷しません.今回は 定義
前のセクションでは,ジェネレータを用いて順序非同期コールバックを構築する新しい方法を学習した.
deferreds
、非同期操作をリンクする方法は2つあります.時には、しかし、私達は“並列”の1組の非同期の操作を実行する必要があります.Twistedは単一のスレッドのため、それは実際に同時に運行することはできませんが、私達は非同期I/Oを使って1組の任務の上でできるだけ速い仕事をしたいです.私達の詩のクライアントを例にして、それは複数のサーバーから同時に詩をダウンロードします.次から次へとではなく、Twistedを使って詩をダウンロードするすべての特徴です.
結果として、すべての詩クライアントは問題を解決する必要があります.どのようにして起動したすべての非同期操作が完了したことを知っていますか.クライアント7.0のような結果セットをリストにまとめることで 結果 成功した結果を収集する以外に、失敗に注意しなければならない.そうしないと、失敗はプログラムをデッドサイクルにし、仕事が必要だと思っている.
予想通り、Twistedにはこの問題を解決するための抽象層が含まれています.見てみましょう.
DeferredList
DeferredList
クラスは私たちに defered
オブジェクトリストを1つとして表示 defered
オブジェクト.この方法により、ファミリーの非同期操作を開始し、それらがすべて完了した後に通知を得る(成功または失敗にかかわらず).いくつかの例を見てみましょう.にある deferred-list/deferred-list-1.py で、次のコードを見つけることができます.
from twisted.internet import defer
def got_results(res):
print 'We got:', res
print 'Empty List.'
d = defer.DeferredList([])
print 'Adding Callback.'
d.addCallback(got_results)
実行すると、次のような出力が得られます.
Empty List.
Adding Callback.
We got: []
次の点に注意してください.
DeferredList
Pythonリストから作成されます.この場合、リストは空ですが、リスト要素が Deferred
対象.DeferredList
それ自体が deferred
(継承 Deferred
).これはあなたが普通のように扱うことができることを意味します. deferred
同様にコールバックとエラーコールバックを追加する.DeferredList
すぐに励起しなければなりません.後で議論します.deferred
リストの結果自体もリスト(空)である.from twisted.internet import defer
def got_results(res):
print 'We got:', res
print 'One Deferred.'
d1 = defer.Deferred()
d = defer.DeferredList([d1])
print 'Adding Callback.'
d.addCallback(got_results)
print 'Firing d1.'
d1.callback('d1 result')
次に、
deferred
エレメント DeferredList
リストには、次のような出力が表示されます.One Deferred.
Adding Callback.
Firing d1.
We got: [(True, 'd1 result')]
次の点に注意してください.
DeferredList
リスト内の deferred
. deferred
の結果.deferreds
(deferred-list/deferred-list-3.py): from twisted.internet import defer
def got_results(res):
print 'We got:', res
print 'Two Deferreds.'
d1 = defer.Deferred()
d2 = defer.Deferred()
d = defer.DeferredList([d1, d2])
print 'Adding Callback.'
d.addCallback(got_results)
print 'Firing d1.'
d1.callback('d1 result')
print 'Firing d2.'
d2.callback('d2 result')
次のような出力が得られます.
Two Deferreds.
Adding Callback.
Firing d1.
Firing d2.
We got: [(True, 'd1 result'), (True, 'd2 result')]
現在
DeferredList
の結果は非常に明確で、少なくとも私たちの使用方法では、リストであり、要素の個数とインプットコンストラクタの deferred
リスト要素の個数は同じで、結果リストの要素は元の deferreds
結果情報は、少なくとも deferred
正常に戻りました.これは DeferredList
すべての元のリストの deferreds
すべて励起されます.空のリストで作成されます. DeferredList
何も待つ必要がないので、すぐに励起されます. deferreds
. では、最終結果リストの要素の順序はどうですか?次のコード( deferred-list/deferred-list-4.py):
from twisted.internet import defer
def got_results(res):
print 'We got:', res
print 'Two Deferreds.'
d1 = defer.Deferred()
d2 = defer.Deferred()
d = defer.DeferredList([d1, d2])
print 'Adding Callback.'
d.addCallback(got_results)
print 'Firing d2.'
d2.callback('d2 result')
print 'Firing d1.'
d1.callback('d1 result')
ここではd 2を励起してからd 1を励起し,構造パラメータの
deferred
リスト内のd 1,d 2は元の順序である.出力結果は以下の通りである.Two Deferreds.
Adding Callback.
Firing d2.
Firing d1.
We got: [(True, 'd1 result'), (True, 'd2 result')]
出力リストの結果の順序と元の
deferred
リストの順序は、 deferred
たまたま励起された順序は、各結果を生成する対応する操作(どの詩がどのサーバから来たのか)と簡単に結びつけることができるため、非常に良い.リストの1つ以上が
deferreds
失敗したらどうする?上の結果のTrueは何の役に立ちますか?もう1つの例(deferred-list/deferred-list-5.py):from twisted.internet import defer
def got_results(res):
print 'We got:', res
d1 = defer.Deferred()
d2 = defer.Deferred()
d = defer.DeferredList([d1, d2], consumeErrors=True)
d.addCallback(got_results)
print 'Firing d1.'
d1.callback('d1 result')
print 'Firing d2 with errback.'
d2.errback(Exception('d2 failure'))
ここで、d 1は正常な結果で励起され、d 2はエラーで励起される.
consumerErrors
オプション、説明をお待ちしています.出力結果は次のとおりです.Firing d1.
Firing d2 with errback.
We got: [(True, 'd1 result'), (False, <twisted.python.failure.Failure <type 'exceptions.Exception'>>)]
今回d 2に対応するメタグループが2番目の位置に1つ現れた
Failure
、そして最初の位置は False
.これで DeferredList
の動作原理は非常に明確です(ただし、以下の説明を参照してください).DeferredList
ひとつで deferred
オブジェクトリスト作成.DeferredList
それ自体が deferred
、結果はリストであり、長さは deferred
リストは同じです.deferred
励起された後、 DeferredList
励起されます.deferred
.もしそれが deferred
正常に返され、対応する要素は(True,result)、失敗した場合は(False,failure).DeferredList
失敗はしない. deferred
の戻り結果が何であるかは、結果リストに集約されます(同様に、以下を参照).では、転送されることについてお話ししましょう.
DeferredList
の consumeErrors
オプションを選択します.このオプション(deferred-list/deferred-list-6.py)を入力せずに上記の同じコードを実行すると、次の出力が得られます.Firing d1.
Firing d2 with errback.
We got: [(True, 'd1 result'), (False, >twisted.python.failure.Failure >type 'exceptions.Exception'<<)]
Unhandled error in Deferred:
Traceback (most recent call last):
Failure: exceptions.Exception: d2 failure
「Unhandled error in Deferred」メッセージは
deferred
ごみ回収時に生成され、最後のコールバックに失敗したことを示します.このメッセージは、潜在的な非同期エラーを完全にキャプチャしていないことを示しています.私たちの例では、どこから来たのでしょうか.明らかに DeferredList
は、正常に戻ったので、d 2から来たに違いありません.DeferredList
監視されていることを知る必要があります deferred
いつ励起するか. DeferredList
通常の方法で deferred
コールバックとエラーコールバックを追加します.デフォルトでは、このコールバック(またはエラー)は元の結果(またはエラー)を返します.最終結果リストに入れると、エラーコールバックは元の結果に戻ります. failure
その後、次のエラーコールバックがトリガーされ、d 2は励起後も失敗状態を維持する.しかしconsumeErrors=Trueを
DeferredList
、各 deferred
Noneに戻るエラーコールバックを追加します.つまり、このエラーを「消費」し、警告情報をキャンセルします.私たちは同様にd 2に自分のエラーコールバックを追加してエラーを処理することができます. deferred-list/deferred-list-7.py. クライアント8.0
詩歌クライアント8.0のリリースを取得しました!クライアント使用
DeferredList
すべての詩がいつ完成するか(または失敗するか)を発見します.新しいクライアントは twisted-client-8/get-poetry.py.同様に、唯一の変化は poetry_main、重要な変化を見てみましょう....
ds = []
for (host, port) in addresses:
d = get_transformed_poem(host, port)
d.addCallbacks(got_poem)
ds.append(d)
dlist = defer.DeferredList(ds, consumeErrors=True)
dlist.addCallback(lambda res : reactor.stop())
君は クライアント7.0 の該当部分を比較する.
クライアント8.0ではpoem_は必要ありませんdoneコールバックとresultsリストです.逆に、getからtransformed_poemが返す
deferred
dsリストを入れてから DeferredList
. DeferredList
すべての詩が完成したり失敗したりする前に励まされることはありません.私たちはただ DeferredList
コールバックを追加して閉じる reactor
.私たちの場合、使用していません. DeferredList
戻った結果、私たちはすべてのことがいつ終わるかを知る必要があります.それだけです.ディスカッション
ビジュアル化
DeferredList
の働き方:図37:
DeferredList
の結果とても簡単で、本当です.
DeferredList
私达は関连していないで、およびあれらの私达の以上述べた行为を変えるオプション.私达は参考练习の中でこれらを読者に残して自分で探求します.にある :doc:`p19` ではさらにご紹介します
Deferred
Twisted 10.1.0が提案した最新の特性を含むクラス.参考練習
DeferredList
のソースコード.fireOnOneCallback
および fireOnOneErrback
.そのうちの1つ(または両方)を使用するシナリオを実装します.DeferredLists
リストの作成 DeferredList
そうですか.もしそうなら、結果は何ですか?DeferredList
の結果.DeferredDict
の文法を実現し、それを実現する.