node js mongo db dependencies(找不到doc)

时间:2015-09-02 02:31:40

标签: node.js mongodb mongoose async.js apn

我有以下代码:

var method = PushLoop.prototype;
var agent = require('./_header')  
var request = require('request');
var User = require('../models/user_model.js');
var Message = require('../models/message_model.js');
var async = require('async')

function PushLoop() {};

    method.startPushLoop = function() {

     getUserList()

    function getUserList() {        

        User.find({}, function(err, users) {            
            if (err) throw err;
            if (users.length > 0) {              
                 getUserMessages(users) 
            } else {              
                setTimeout(getUserList, 3000)
            }                   
        });
    }

    function getUserMessages(users) {
         // console.log("getUserMessages")
         async.eachSeries(users, function (user, callback) {

              var params = {
                  email: user.email,
                pwd: user.password,
                token: user.device_token
              }                       
                  messageRequest(params)                             
              callback(); 
            }, function (err) {
              if (err) {
                console.log(err)
                    setTimeout(getUserList, 3000)                
              }               
            });
    }

    function messageRequest(params) {

            var url = "https://voip.ms/api/v1/rest.php?api_username="+ params.email +"&api_password="+ params.pwd +"&method=getSMS&type=1&limit=5"                                      
            request(url, function(err, response, body){ 

                if (!err) {

                    var responseObject = JSON.parse(body);                                          
                var messages = responseObject.sms   

                    if (responseObject["status"] == "success")  {                                                                                                               
                        async.eachSeries(messages, function(message, callback){     
                          console.log(params.token)         
                            saveMessage(message, params.token)
                            callback();

                        }, function(err) {
                            if (err) {
                                console.log(err)
                            }
                            // setTimeout(getUserList, 3000)                            
                        })
                    } else {
                        // setTimeout(getUserList, 3000)    
                    }
                } else {
                    console.log(err)
                    // setTimeout(getUserList, 3000)
                }           

            });
            setTimeout(getUserList, 3000)
    }

    function saveMessage(message, token) {
         // { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } }
        // Message.find({ $and: [{ message_id: message.id}, {device_token: token}]}, function (err, doc){             
            Message.findOne({message_id: message.id}, function (err, doc){

          if (!doc) {                    
                  console.log('emtpy today')                
                    var m = new Message({
                          message_id: message.id, 
                          did: message.did,
                          contact: message.contact, 
                          message: message.message,
                          date: message.date,
                          created_at: new Date().toLocaleString(),
                          updated_at: new Date().toLocaleString(),
                          device_token: token    
                        });             
                      m.save(function(e) {
                            if (e) {                                
                                console.log(e)
                            }   else {
                                 agent.createMessage()               
                                  .device(token)
                                  .alert(message.message)
                                  .set('contact', message.contact)
                                  .set('did', message.did)
                                  .set('id', message.id)
                                  .set('date', message.date)
                                  .set('message', message.message)                    
                                  .send();                                
                            }                                       
                        });       
          }                                                     
        }) //.limit(1); 
    }

};

module.exports = PushLoop;

在我的开发环境中实际上工作得非常好 - 但是在生产中(我使用的是Openshift)mongo文档被保存在无限循环中,所以看起来(if(!doc))条件总是返回true因此每次都会创建文档。不确定这是否是一个猫鼬问题 - 我也试过&#34;发现&#34;方法而不是&#34; findOne&#34;。我的dev env有节点0.12.7,Openshift有0.10.x - 这可能是问题,我还在调查 - 但是如果有人能发现我在逻辑/代码中看不到的错误,请告诉我< / p>

谢谢!

1 个答案:

答案 0 :(得分:0)

我通过使用类似“系列”模式并在users数组上使用shift方法解决了这个问题。 mongoose upsert findOneOrCreate是好的,但是如果找到一个找到的文档,则返回该文档,如果找不到并因此创建了该文档,则返回该文档。因此我无法区分新插入的doc与找到的doc,所以使用了相同的findOne函数,如果没有找到doc,则返回null我只是创建它并发送推送通知。仍然丑陋,我知道我可以使用promises或async lib,将来可能会重构。这适用于现在

function PushLoop() {};

    var results = [];   
    method.go = function() {
        var userArr = [];
        startLoop()

        function startLoop() {  

        User.find({},function(err, users) {         
            if (err) throw err;
            users.forEach(function(u) {             
                userArr.push(u)                         
            })                      
            function async(arg, callback) {

                var url = "https://voip.ms/api/v1/rest.php?api_username="+ arg.email +"&api_password="+ arg.password +"&method=getSMS&type=1&limit=5"                                       

                    request.get(url, {timeout: 30000}, function(err, response, body){ 
                        if (!err) {                                         
                            var responseObject = JSON.parse(body);                                          
                        var messages = responseObject.sms   
                        var status = responseObject.status
                        if (status === "success") {


                        messages.forEach(function(m) {

                            var message = new Message({
                                      message_id: m.id, 
                                      did: m.did,
                                      contact: m.contact, 
                                      message: m.message,
                                      date: m.date,
                                      created_at: new Date().toLocaleString(),
                                      updated_at: new Date().toLocaleString(),
                                      device_token: arg.device_token     
                                    });                             
                                    var query = { $and : [{message_id: m.id}, {device_token: arg.device_token}] }
                                    var query1 = { message_id: m.id }


                                    Message.findOne(query).lean().exec(function (err, doc){

                                             if (!doc || doc == null) {                                              
                                                            message.save(function(e) {
                                                                console.log("message saved")
                                                                if (e) {
                                                                    console.log("there is an error")
                                                                    console.log(e)
                                                                } else {

                                                                    console.log(message.device_token)
                                                                        var messageStringCleaned = message.message.toString().replace(/\\/g,"");                                                                                                                                                                            

                                                                        var payload = {
                                                                            "contact" : message.contact,
                                                                            "did" : message.did,
                                                                            "id" : message.message_id,
                                                                            "date" : message.date,
                                                                            "message" : messageStringCleaned
                                                                        }                                                                       

                                                                    var note = new apns.Notification();
                                                                    var myDevice = new apns.Device(message.device_token);
                                                                    note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
                                                                    note.badge = 3;                                                                 
                                                                    note.alert = messageStringCleaned;
                                                                    note.payload = payload;
                                                                    apnsConnection.pushNotification(note, myDevice);                                                                    
                                                            }
                                                            })                                                                                                                                                                                    
                                                }                                                                                                                                                               
                                            }); 
                                    });                     
                        }
                          else {
                            console.log(err)
                          }
                        }                   
                    }); 

              setTimeout(function() {             
                callback(arg + "testing 12"); 
              }, 1000);
            }
            // Final task (same in all the examples)            
            function series(item) {
                  if(item) {
                    async( item, function(result) {                                             
                      results.push(result);       
                      return series(userArr.shift());
                    });
                  } else {
                    return final();
                  }
            }
            function final() { 
                console.log('Done'); 
                startLoop();
            }

            series(userArr.shift())
        });
    }
}


module.exports = PushLoop;