NISによってAPI呼び出しの結果が古い場合について

xiaca ()
自前のプログラムにてアカウント情報の取得を行っていたところ、NISによって取得結果が古いものがありま した(2018年1月31日時点)

以下のNISに対してアカウント情報を取得したところ2018年01月05日のハーベスト結果がまだ反映さ れていませんでした。
・「http://27.134.244.125:7890/account/g...NMI5NPPH6B7JSH 」の場合
harvestedBlocks:4

その他のNISでは2018年01月05日のハーベスト結果が反映されていました。
・「http://go.nem.ninja:7890/account/get...NMI5NPPH6B7JSH 」の場合、
harvestedBlocks:5


このような事はたまにあるのでしょうか?
たまにある場合、回避するために何かできることはありますでしょうか?
※今のところ結果が古いのを確認しているのは「27.134.244.125 」だけです。

ちなみに、peer-list/allで取得した結果には特にバージョン等の差異はありませんでした。
・go.nem.ninja
{
"metaData": {
"features": 1,
"application": null,
"networkId": 104,
"version": "0.6.95-BETA",
"platform": "Oracle Corporation (1.8.0_121) on Linux"
},
"endpoint": {
"protocol": "http",
"port": 7890,
"host": "go.nem.ninja"
},
"identity": {
"name": "[c=#86c0e9]go[/c]",
"public-key": "26a3ac4b24647c77dc87780a95e50cb8d7744966e4569 e3ac 24e52c532c0cd0d"
}
}

・27.134.244.125
{
"metaData": {
"features": 1,
"application": null,
"networkId": 104,
"version": "0.6.95-BETA",
"platform": "Oracle Corporation (1.8.0_151) on Windows Server 2012 R2"
},
"endpoint": {
"protocol": "http",
"port": 7890,
"host": "27.134.244.125"
},
"identity": {
"name": "all4nem",
"public-key": "89d9e7eae44e2751ec3612844dd3370b50bcc434a3b34 3366 4f7ec44bc48e57f"
}
}



ちなみに以下は本来やろうとしていたことです。
自前プログラムを作るにあたって、あまり一つのNISに対してAPIを呼ぶのもよくないかと考えました。
そのため予め「http://go.nem.ninja:7890/node/peer-list/all 」のAPIを呼びNISの一覧を取得し、その中から毎回ランダムにNISを選んで、APIを呼ぶような中継 サーバを作っておりました。

その処理自体はできたのですが、自前プログラムで画面の表示結果が違うことに気づき、
調べたところNISごとにアカウント情報の取得結果が違うことに気づき質問させていただいた次第です。

xiaca ()
本日「http://27.134.244.125:7890/account/g...NMI5NPPH6B7JSH 」にアクセスしたところ、応答がなくなっておりました。やはり何かまずいところがあったのかもしれません。
しかし、依然として「http://go.nem.ninja:7890/node/peer-list/all 」や「https://supernodes.nem.io/nodes 」には「27.134.244.125 」の記載があります。
本当に有効なスーパーノードを取得する方法についてもうちょっと調べてみます。

siwong ()
あぁ、この辺のノード選択は知見をまとめたいところですね。
自前でノードを建てる場合以外は、どのサービスでも必要になるでしょうし。

基本的な流れは以下の様な感じでしょうか?
(+αでNISのバージョンチェックとか諸々追加できそうですが)

1.Activeノード一覧取得
2.一覧からランダムにノードを取得
3.対象ノードの状態確認
3.1.対象ノードのステータス確認
3.2.対象ノードのチェーンの高さ取得
3.3.最大チェーンの高さ取得
3.4.チェーンの高さ比較(最大チェーンと一致を必須にするか、数ブロック程度は許容するかはお好みで)
4.正常なノードが取れるまで2~3を繰り返し


注意点としては、以下の様な感じですかね。

・ノードが停止しているとHTTPエラーが発生する

・ノード(NIS)が再起動するとブロックの同期処理が発生する
 ※この間はいくつかのAPIでエラーになります

・APIによってはNISエラーや例外ではなく無反応(?)になることがある
 ※推測ではサーバーのメモリ不足等でブロック同期が遅々として進まないノードだと無反応になった可能性が高いです
 ※チェーンの高さ取得(/chain/height)だとエラーが返るのに、最大チェーン取得(max-chain-height)だと反応が返ってこなかった記憶あり
  (適当にタイムアウトを設定した方が良いかも&駄目なときは別のノードから最大チェーンを取得)


ちなみに、Activeノード一覧は毎回取得せずにある程度安定しているのをストックしておくとか、Alice系のノード(財団管理のノード?)を一覧化しておくとかでも良いかと。

あと、安定性を求めるのならランダム抽出を1つではなく複数抽出にして結果を比較するとかも考えられますが、どこまで冗長にするかはシステム次第ですね。
バックグラウンドで安定しているノードを定期的に探す処理を流しておいて、一覧を定期的に更新しても良いし。

xiaca ()
Tanugami様、siwong様、回答頂きありがとうございます。
今の処理の中にSNを確認する処理を追加してみたいと思います!

xiaca ()
回答の内容でやりたかった処理ができました!
もう少し処理を詰めるとこもありますが、
Githubにアップしたので共有させていただきます。

https://github.com/scrpgil/transfer-nem-api

siwong ()
備忘録がてら追記@2018/04/06
・ノードの高さが同じでも、チェーンがフォークしている可能性がある(現状では可能性は低いが)
・nemは360ブロック(6時間)経過で確定なので、直近360ブロックまでは変動する可能性を考慮すること
・直近nブロックを複数ノードから取得し、差異が無いか検証する方法も考えられるが、対象ノードの数によって精度や負荷が変わるので注意