node-retryとasync.seriesをっかって非同期逐次処理の再試行

Date
February 28, 2014
Tags
Node JavaScript

Node.jsにぉぃて、非同期で取ってきたデータを基にして、
また更に非同期処理をして、成功したらまた非同期処理をして、
とかゅーのを考ぇます

caolan/asyncで逐次処理をかぃてみる

この場合のコントロールフローとしてゎ
caolan/asyncseries()waterfall()がぃぃと思ぃます

npm install async --save

async.series()をっかってかくと、こんなふうになります

https://gist.github.com/ayapi/9257773

サンプルなのでsetTimeout()で結果を渡すょーにしてますが、
実際にゎ、httpリクエストとかのコールバックでdoneを呼びます

getが1秒後に成功してから、sendが実行されます
けどsendでゎ1秒後に必ずエラーが発生して、
saveゎ実行されずにぉゎり、とゅーかんじです

出力ゎ以下のょーになります

get
send
send:failed

node-retryで再試行処理を追加する

ネットワークが不安定だったりすると、リトライ処理をしたくなります
成功するまで何回もゃらせて、けどN回連続で失敗したら、
ちょっともぅぁきらめる、ってかんじのゃっです

tim-kos/node-retryゎ、
日本語の情報がほとんどなぃんですけど、
リトライ処理をかんたんにかけるライブラリです

これをっかって、さっきのasync.series()のコードに
再試行処理を追加してみます

npm install retry --save

オプションで、再試行回数の上限と、
失敗してから再試行するまでにちょっと時間を空けるってゅー、
待ち時間に関する設定ができます

再試行の回数が増ぇてぃくごとに、
待ち時間を長くしてぃくょーな挙動がデフォルトみたぃです
ぁたまぃぃーって思ぃます↑

けど今回ゎ「そーゅーのぃぃから」ってなったので、なしにしてみます

https://gist.github.com/ayapi/9256588#file-retryseries-js-L22-L26

今回のサンプルだと、sendで失敗するまでに、
getで取ってこれるデータの状態が変ゎってるかもしれなぃ、
とか考ぇはじめると、sendで失敗しちゃった時にゎ、
最初に戻ってゃり直したぃ、ってなったりします

そーゅーのゎ、async.series()をまるごと、
operation.attempt()に入れたらできます

https://gist.github.com/ayapi/9256588#file-retryseries-js-L28-L40

operation.retry(err)ゎ、
引数errにエラーオブジェクトが渡された時にゎ、
再試行回数の上限をチェックして、
まだゃるならtrue、ぁきらめるならfalseを返します
そしてtrueならoperation.attempt()が再び呼ばれます

引数errがエラーオブジェクトじゃなぃ時ゎ、
falseを返します

っまり、falseが返る時ゎ、
結果ゎどーぁれ、ぉゎる時、とゅーことです

operation.mainError()ゎ、ぃちばん多くでたエラーを返すみたぃです
error.messageの内容にょってカウントしてるみたぃです
今回ゎ毎回'send:failed'なのでぁんまり意味なぃですけど、
実際にっかぅ時ゎ、
試行回数が重なればエラーの内容もちがぅ場合もぁりぇますので
こーゅー便利メソッドが用意されてるみたぃです

完成ばん

てことで、かけたコードゎこれです\(^o^)/

https://gist.github.com/ayapi/9256588

出力ゎ以下のょーになります

get
send
get
send
get
send
get
send
get
send
send:failed