2014-11-23 5 views
0

У меня возникают проблемы, когда приложение моего узла внезапно начинает потреблять много CPU. Я подозреваю, что функция ниже застряла как-то ..NodeJS застревает в обратном вызове

Client.prototype.countActiveChatsRedis = function (userID, agentID, obj, callback) { 
    var count = 0; 

    pub.keys("widgetActive:" + userID + ":*", function(err, key) { 

     if(err !== null) { 
      console.log("Redis error..... --> " + err); 
      callback(count, obj);   
     } 

     if(key && key.length > 0) { 
      pub.mget(key, function(err, data) { 
       if(data) { 
        for(var i = 0; i < data.length;i++) { 
         if(data[i]) { 
          var arr = data[i].split(","); 

          if(arr[2] == agentID) { 
           if (Number(arr[3]) > 0) { 
            count++; 
           }       
          } 
         } 
        } 

        callback(count, obj); 
       } 
      });   
     } else { 
      callback(count, obj);   
     } 
    }); 
} 

Любые идеи в чем проблема? В любом случае, когда он мог бы избежать отправки обратного вызова?

Эта функция работает примерно 50 раз в секунду.

ответ

0

вы должны всегда возвращение ваши обратные вызовы, чтобы убедиться, что ваша функция завершается корректно и возвращает управление в контексте вызова:

Client.prototype.countActiveChatsRedis = function (userID, agentID, obj, callback) { 
var count = 0; 

pub.keys("widgetActive:" + userID + ":*", function(err, key) { 

    if(err !== null) { 
     console.log("Redis error..... --> " + err); 
     return callback(count, obj);   
    } 

    if(key && key.length > 0) { 
     pub.mget(key, function(err, data) { 
      if(data) { 
       for(var i = 0; i < data.length;i++) { 
        if(data[i]) { 
         var arr = data[i].split(","); 

         if(arr[2] == agentID) { 
          if (Number(arr[3]) > 0) { 
           count++; 
          }       
         } 
        } 
       } 

       return callback(count, obj); 
      } 
     });   
    } else { 
     return callback(count, obj);   
    } 
}); 
} 
+0

Считаете ли вы, что это могло быть проблемой? – user3490755

+1

Нет, я этого не делаю. Я просто написал это для удовольствия –

3

Это плохая практика, чтобы использовать КЛЮЧИ в производственной среде. Процитируем Redis сам хозяин:

Внимание: рассмотреть КЛЮЧИ как команда, которая должна использоваться только в производственных средах с крайней осторожностью. Он может испортить производительность , когда он выполняется против больших баз данных. Эта команда предназначена для для отладки и специальных операций, таких как изменение вашего пространства клавиш . Не используйте KEYS в вашем обычном коде приложения. Если вы используете , ищите способ поиска ключей в подмножестве вашего пространства ключей, рассмотрите с помощью SCAN или наборов.

Всякий раз, когда вы добавляете ключ с этим префиксом, просто добавьте его в набор под названием «widgetActive» идентификатор пользователя или любые другие данные, которые вам нужны. вы также можете использовать HASH, если вам нужно сохранить некоторые данные для каждой записи.

+0

Не могли бы вы привести небольшой пример? =) Не уверен, что я следую – user3490755

0

Он застрял, потому что в случае отсутствия данных вызов вызова не вызван.

pub.mget(key, function(err, data) { 
    if(data) { 
    for(var i = 0; i < data.length;i++) { 
     if(data[i]) { 
      var arr = data[i].split(","); 

      if(arr[2] == agentID) { 
      if (Number(arr[3]) > 0) { 
       count++; 
      }       
      } 
     } 
    } 

    // callback(count, obj); // <==== move this callback outside of if (data) 
    } 
    callback(count, obj); // this ensures that callback always gets called 

});  
Смежные вопросы