NIFCLOUD-mbaas / UserCommunity

ニフクラ mobile backend ユーザーコミュニティ
https://mbaas.nifcloud.com/
81 stars 18 forks source link

【javascript】オブジェクトの大量削除(100件以上)について #231

Closed iseki0225 closed 8 years ago

iseki0225 commented 8 years ago

お世話になります。 現在、mbaasを利用し、集計ロジックを作成しております。 新しい集計結果の保存後に、古い集計結果を削除したいので、以下のようなロジックを作成しました。 データが少量の時は問題なかったのですが、データ数が100件を超えたくらいから、削除が上手く出来ません。

//引数のkeyは集計タイミングの判別Keyとなります。
function removeModel(key){
  var query = makeNcmbObject("TestClass")['query'];
  query.notEqualTo("key", key);
  query.limit(100);
  query.skip(0);
    query.find({
        success: function(results) {
            if(results.length === 0){
                return;
            }
            for (var i=0; i < result.length; i++){
                var obj = results[i];
                obj.destroy();
            }
        },
        error: function(error){
            console.log(error);
            return;
        }
    });

個人的な推察ですが、同時接続上限のエラーに引っかかっていると考えています。 以下、ご回答いただけますと幸いです。

1)エラーが発生する原因は他に何かありますでしょうか?

2)保存については、NCMB.Object.saveAllがありますが、destroyについてはそれに相当するものはないのでしょうか?

3)(2)がない場合は、何かよいロジックはありませんでしょうか?

以上、よろしくお願いいたします。

goofmint commented 8 years ago

エラーの原因がわからないので、obj.destroy()の返却値を見てみるのはいかがでしょう。

obj.destroy().then(function () {
  // 削除成功
  console.log("Destroyed");
}, function (err) {
  // エラー
  console.error(err);
});

たぶんこれでエラーが出るのかなと。

iseki0225 commented 8 years ago

早速のご返答ありがとうございます。 なるほど、thenをそういう風に使えば良かったんですね。

早速組み込んで実行したところ、以下のようなエラーが帰ってきていました。

Destroyed
Destroyed
Destroyed
Destroyed
Destroyed
{ code: -1,
  message: 'Error: connect ECONNREFUSED\n    at errnoException (net.js:905:11)\n    at Object.afterConnect [as oncomplete] (net.js:896:19)' }
{ code: -1,
  message: 'Error: connect ECONNREFUSED\n    at errnoException (net.js:905:11)\n    at Object.afterConnect [as oncomplete] (net.js:896:19)' }
================省略================
{ code: -1,
  message: 'Error: connect ECONNREFUSED\n    at errnoException (net.js:905:11)\n    at Object.afterConnect [as oncomplete] (net.js:896:19)' }
{ code: -1,
  message: 'Error: connect ECONNREFUSED\n    at errnoException (net.js:905:11)\n    at Object.afterConnect [as oncomplete] (net.js:896:19)' }
Destroyed
Destroyed
Destroyed
Destroyed
Destroyed

一般的に、ECONNREFUSEDはホストがサービスを拒否した場合に発生すると認識しております。 最初の5つは削除が出来ていることから、

・ホスト側のキューが一杯になった ・クライアント側のキューが一杯になった

上記、いずれかが原因と考えて良いのでしょうか?

以上、よろしくお願いいたします。

iseki0225 commented 8 years ago

調査の追加情報ですが、

ncmb-latest.jsに以下のようにログを仕込み実行したところ

  // AJAX リクエストを処理するための関数 
  NCMB._ajax = function(route, className, method, url, data, signature, timestamp, success, error) {
    //省略
    var xhr = new NCMB.XMLHttpRequest();
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        if (handled) {
          return;
        }
        handled = true;
        if (xhr.status >= 200 && xhr.status < 300) {

        //省略

        } else {
          console.log("xhr.status:"+xhr.status);
          promise.reject(xhr);
        }
      }
    };
    //省略
  };

以下のログが出力されました。

HTTP: HTTP SOCKET ERROR: connect ECONNREFUSED
Error: connect ECONNREFUSED
    at errnoException (net.js:905:11)
    at Object.afterConnect [as oncomplete] (net.js:896:19)
xhr.status:503
error:11:25:5.347
{ code: -1,
  message: 'Error: connect ECONNREFUSED\n    at errnoException (net.js:905:11)\n    at Object.afterConnect [as oncomplete] (net.js:896:19)' }

このことから、サーバーとの通信は出来ているものの、サーバー側で何らかの問題が発生したことが原因と推測しております。 他、何か知見等ございませんでしょうか?

以上、よろしくお願いいたします。

iseki0225 commented 8 years ago

今更な自己解決ですが、以下のようにすることで、同時接続と思われる問題は回避できそうでした。

success: function(results) {
    if(results.length === 0){
        return;
    }
    delte(results);
}

var delete = function(results){
  var obj = results[i];
  obj.destroy();
  results.shift();
  if (results.length > 0){
    setTimeout(function(){delete(results)}, 1000)
  }
}
```;