データを 4 つの異なるノードにファンアウトしたいと考えています。firebaseトランザクションプロセスが失敗する可能性があるため、4つのデータすべてが確実に保存されるようにするための正しいアプローチは何ですか?
データを保存するための 4 つの関数があり、それぞれがトランザクションを呼び出すとします。
編集:
function saveToFirstNode(data, response) {
/*
* @param
* [response] is a callback function
* that indicates whether the save was successful
*/
firebase.database().ref('cars/' + data.carId)
.transaction(function(currentData) {
currentData.distance += data.distance;
return currentData;
}, function(error, commited, snapshot) {
if (error) {
response(false);
} else if (commited) {
response(true)
}
}, false);
}
function saveToSecondNode(data, response) {...}
function saveToThirdNode(data, response) {...}
function saveToFourthNode(data, response) {...}
1.最初のアプローチの使用
このアプローチでは、ネストされたコールバック関数を使用し、保存が成功するたびに progress() を呼び出します。
欠点は、保存プロセスの 1 つが失敗した場合、1 番目から 4 番目までのすべてのデータが再保存されることです。
var queue = new Queue(ref, options, function(data, progress, resolve, reject) {
saveToFirstNode(data, function(success) {
if (success) {
progress(25);
saveToSecondNode(data, function(success) {
if (success) {
progress(50);
saveToThirdNode(data, function(success) {
if (success) {
progress(75);
saveToFourthNode(data, function(success) {
if(success) {
resolve(data);
} else {
reject();
}
});
} else {
reject();
}
});
} else {
reject();
}
});
} else {
reject();
}
});
});
2. 2 番目のアプローチを使用する
このアプローチにより、すべてのデータが保存されることが保証されます。保存処理が失敗した場合、1番目から4番目までではなく、失敗したスペックからリトライします。でも4セーブするだけでやり過ぎだと思いませんか?これは正しいアプローチですか?
queue/specs でスペックを定義します。
{
"save_to_first_node": {
"in_progress_state": "save_to_first_node_in_progress",
"finished_state": "save_to_first_node_finished"
},
"save_to_second_node": {
"start_state": "save_to_first_node_finished",
"in_progress_state": "save_to_second_node_in_progress",
"finished_state": "save_to_second_node_finished"
},
"save_to_third_node": {
"start_state": "save_to_second_node_finished",
"in_progress_state": "save_to_third_node_in_progress",
"finished_state": "save_to_third_node_finished"
},
"save_to_fourth_node": {
"start_state": "save_to_third_node_finished",
"in_progress_state": "save_to_fourth_node_in_progress"
}
}
キュー コード:
var saveToFirstNodeOptions = {'specId': 'save_to_first_node'};
var saveToFirstNodeQueue = new Queue(ref, saveToFirstNodeOptions, function(data, progress, resolve, reject) {
saveToFirstNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
var saveToSecondNodeOptions = {'specId': 'save_to_second_node'};
var saveToSecondNodeQueue = new Queue(ref, saveToSecondNodeOptions, function(data, progress, resolve, reject) {
saveToSecondNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
var saveToThirdNodeOptions = {'specId': 'save_to_third_node'};
var saveToThirdNodeQueue = new Queue(ref, saveToThirdNodeOptions, function(data, progress, resolve, reject) {
saveToThirdNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
var saveToFourthNodeOptions = {'specId': 'save_to_fourth_node'};
var saveToFourthNodeQueue = new Queue(ref, saveToFourthNodeOptions, function(data, progress, resolve, reject) {
saveToFourthNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
正しいアプローチはどれですか? これらの 2 つは完全に異なるアプローチであり、パフォーマンスと有効性の両方に大きな影響を与えるため、この質問は好みではありません。