[解決済み] Firebaseのクラウド機能が非常に遅い
質問
新しいfirebase cloudの機能を利用したアプリケーションを開発しています。現在起こっていることは、トランザクションがキューノードに入れられるということです。そして、関数がそのノードを削除し、正しいノードに置くというものです。これは、オフラインで作業することができるため、実装されています。
現在の問題は、この関数のスピードです。関数自体は400msくらいで終わるので、まあまあです。しかし、エントリーがすでにキューに追加されているのに、関数が非常に長い時間(約8秒)かかることがあるのです。
サーバーの起動に時間がかかっていると思われるのは、最初のアクションの後にもう一回アクションを行ったときです。というのも、最初のアクションの後にもう一度アクションを実行すると、時間が大幅に短縮されるからです。
この問題を解決する方法はあるのでしょうか?この下に、私たちの関数のコードを追加しました。何も問題はないと思われますが、念のため追加しておきました。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const database = admin.database();
exports.insertTransaction = functions.database
.ref('/userPlacePromotionTransactionsQueue/{userKey}/{placeKey}/{promotionKey}/{transactionKey}')
.onWrite(event => {
if (event.data.val() == null) return null;
// get keys
const userKey = event.params.userKey;
const placeKey = event.params.placeKey;
const promotionKey = event.params.promotionKey;
const transactionKey = event.params.transactionKey;
// init update object
const data = {};
// get the transaction
const transaction = event.data.val();
// transfer transaction
saveTransaction(data, transaction, userKey, placeKey, promotionKey, transactionKey);
// remove from queue
data[`/userPlacePromotionTransactionsQueue/${userKey}/${placeKey}/${promotionKey}/${transactionKey}`] = null;
// fetch promotion
database.ref(`promotions/${promotionKey}`).once('value', (snapshot) => {
// Check if the promotion exists.
if (!snapshot.exists()) {
return null;
}
const promotion = snapshot.val();
// fetch the current stamp count
database.ref(`userPromotionStampCount/${userKey}/${promotionKey}`).once('value', (snapshot) => {
let currentStampCount = 0;
if (snapshot.exists()) currentStampCount = parseInt(snapshot.val());
data[`userPromotionStampCount/${userKey}/${promotionKey}`] = currentStampCount + transaction.amount;
// determines if there are new full cards
const currentFullcards = Math.floor(currentStampCount > 0 ? currentStampCount / promotion.stamps : 0);
const newStamps = currentStampCount + transaction.amount;
const newFullcards = Math.floor(newStamps / promotion.stamps);
if (newFullcards > currentFullcards) {
for (let i = 0; i < (newFullcards - currentFullcards); i++) {
const cardTransaction = {
action: "pending",
promotion_id: promotionKey,
user_id: userKey,
amount: 0,
type: "stamp",
date: transaction.date,
is_reversed: false
};
saveTransaction(data, cardTransaction, userKey, placeKey, promotionKey);
const completedPromotion = {
promotion_id: promotionKey,
user_id: userKey,
has_used: false,
date: admin.database.ServerValue.TIMESTAMP
};
const promotionPushKey = database
.ref()
.child(`userPlaceCompletedPromotions/${userKey}/${placeKey}`)
.push()
.key;
data[`userPlaceCompletedPromotions/${userKey}/${placeKey}/${promotionPushKey}`] = completedPromotion;
data[`userCompletedPromotions/${userKey}/${promotionPushKey}`] = completedPromotion;
}
}
return database.ref().update(data);
}, (error) => {
// Log to the console if an error happened.
console.log('The read failed: ' + error.code);
return null;
});
}, (error) => {
// Log to the console if an error happened.
console.log('The read failed: ' + error.code);
return null;
});
});
function saveTransaction(data, transaction, userKey, placeKey, promotionKey, transactionKey) {
if (!transactionKey) {
transactionKey = database.ref('transactions').push().key;
}
data[`transactions/${transactionKey}`] = transaction;
data[`placeTransactions/${placeKey}/${transactionKey}`] = transaction;
data[`userPlacePromotionTransactions/${userKey}/${placeKey}/${promotionKey}/${transactionKey}`] = transaction;
}
解決方法は?
ファイヤーベイザーはこちら
いわゆる機能のコールドスタートが起きているようですね。
しばらく関数が実行されていない場合、Cloud Functionsは関数をより少ないリソースで実行できるモードにします。そして、再び関数を叩くと、このモードから環境が復元される。復元にかかる時間は、固定コスト(例:コンテナの復元)と一部変動コスト(例:ノードモジュールを多く使っている場合は時間がかかる)で構成されている。
私たちはこれらの操作のパフォーマンスを継続的に監視し、開発者の体験とリソースの使用との間の最適な組み合わせを確保しています。そのため、これらの時間は時間の経過とともに改善されることが期待されます。
良いニュースは、これは開発中にしか経験しないはずだということです。一度、実稼働環境で関数が頻繁に起動されるようになれば、コールドスタートに陥ることはほとんどありません。
関連
-
[解決済み】ENOENT, そのようなファイルまたはディレクトリがありません。
-
[解決済み] のエラーが発生しました。これはおそらくnpmの問題ではありません。上に追加のログ出力があると思われます
-
[解決済み] joiライブラリを使用して2つの時間を比較する方法
-
[解決済み] E: npm パッケージを見つけることができません。
-
[解決済み] nodejsでfindAllのソート順を続編にする
-
[解決済み] express は `body-parser deprecated undefined extended` としてエラーを投げます。
-
[解決済み] NodeJsのSequelizeでautoIncrementはどのように動作するのですか?
-
[解決済み] エラーです。Cannot find module 'ejs'
-
[解決済み] バルク更新を行う。
-
[解決済み] node.js - リクエスト - "emitter.setMaxListeners() "はどのように?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 再インストールを繰り返しても、npm run でモジュール 'sass' が見つからない。
-
[解決済み】エラーです。EACCES: 権限が拒否されました、アクセス '/usr/local/lib/node_modules' 。
-
[解決済み】モジュール 'internal/util/types' が見つかりません。
-
[解決済み】Mongooseで配列の値を更新する方法
-
[解決済み】E11000重複キーエラー mongodb mongooseのインデックス
-
[解決済み】AWS lambda function エラー - モジュール 'index' をインポートできません。エラー
-
[解決済み] npm install エラー - ローカルの発行者証明書を取得できません。
-
[解決済み] E: npm パッケージを見つけることができません。
-
[解決済み] nvm は npm config の "prefix" オプションと互換性がありません。
-
[解決済み] Express.js req.bodyが未定義です。