Почему мой мульти не работает при проверке возврата команды sadd (** insertRows **)? - PullRequest
0 голосов
/ 21 июня 2020

enter image description here

Why does my multi not work when checking the return of the sadd command (** insertRows **)??

 InserirNovoCliente : function(cliente,zona){ 
    return new Promise(function(fullfill,reject){ 
      var  sadd  = util.promisify(cliente_redis.sadd).bind(cliente_redis);
      cliente_redis.sismember("clientes_visualizadores",cliente.ip,function(err,response){
        console.log('response',response);  
        if(response  == 0){
          sadd("clientes_visualizadores",cliente.ip).then((insertRows)=>{
            console.log('insertRows',insertRows);
            if(insertRows == 1){
              let multi   = cliente_redis.multi();    
              multi.hmset("cliente:"+cliente.ip,cliente);
              multi.hincrby("stats:clientes","conectados",1);
              multi.hincrby("stats:zonas:"+zona.id_zona+":clientes","conectados",1);
              multi.sadd("stats:zonas:"+zona.id_zona+":clientes:ip",cliente.ip); 
              multi.sadd("cliente:"+cliente.ip+":zonas",zona.id_zona); 
              multi.exec((err, replies)=>{ 
                // Multi return replies equal null         
                if(err) throw err;
                if(replies === null) reject(); 
                else{
                  cliente_redis.smembers("clientes_visualizadores",function(err,resp){ console.log('clientes_visualizadores:new:'+ resp.length);  }); 
                  cliente_redis.hmget("stats:clientes",'conectados',function(err,resp){ console.log('stats:clientes:new:'+ resp);  }); 
                  console.log(replies);
                  fullfill();
                } 
              });
            }
          }); 
        }
      });
    });     
  },

Or this code that I tried too

InserirNovoCliente : function(cliente,zona){ 
    return new Promise(function(fullfill,reject){ 
      cliente_redis.sismember("clientes_visualizadores",cliente.ip,function(err,response){
        console.log('response',response);  
        if(response  == 0){
          var multi   = cliente_redis.multi();   
          multi.sadd("clientes_visualizadores",cliente.ip,function(err,insertRows){
            console.log('insertRows',insertRows);
            if(insertRows == 1){ 
              multi.hmset("cliente:"+cliente.ip,cliente);
              multi.hincrby("stats:clientes","conectados",1);
              multi.hincrby("stats:zonas:"+zona.id_zona+":clientes","conectados",1);
              multi.sadd("stats:zonas:"+zona.id_zona+":clientes:ip",cliente.ip); 
              multi.sadd("cliente:"+cliente.ip+":zonas",zona.id_zona); 
              multi.exec((err, replies)=>{          
                if(err) throw err;
                if(replies === null) reject(); 
                else{
                  cliente_redis.smembers("clientes_visualizadores",function(err,resp){ console.log('clientes_visualizadores:new:'+ resp.length);  }); 
                  cliente_redis.hmget("stats:clientes",'conectados',function(err,resp){ console.log('stats:clientes:new:'+ resp);  }); 
                  console.log(replies);
                  fullfill();
                } 
              });
            }
          });
        }
      });
    });     
  },

These two codes never execute multi and return var replies null. But if I do the code snippet below it works. The problem is that, if a user repeatedly connects to the socket, a race condition happens and counts twice in the stats:clientes;

  InserirNovoCliente : function(cliente,zona){ 
    return new Promise(function(fullfill,reject){ 
      cliente_redis.sismember("clientes_visualizadores",cliente.ip,function(err,response){
        console.log('response',response);  
        if(response  == 0){
          let multi   = cliente_redis.multi();  
          multi.sadd("clientes_visualizadores",cliente.ip); 
          multi.hmset("cliente:"+cliente.ip,cliente);
          multi.hincrby("stats:clientes","conectados",1);
          multi.hincrby("stats:zonas:"+zona.id_zona+":clientes","conectados",1);
          multi.sadd("stats:zonas:"+zona.id_zona+":clientes:ip",cliente.ip); 
          multi.sadd("cliente:"+cliente.ip+":zonas",zona.id_zona); 
          multi.exec((err, replies)=>{          
            if(replies === null) reject(); 
            else{
              cliente_redis.smembers("clientes_visualizadores",function(err,resp){ console.log('clientes_visualizadores:new:'+ resp.length);  }); 
              cliente_redis.hmget("stats:clientes",'conectados',function(err,resp){ console.log('stats:clientes:new:'+ resp);  }); 
              console.log(replies);
              fullfill();
            } 
          });
        }
      });
    });     
  },

Correct log output

enter image description here

Log output causing the counting error in collection redis stats:clientes введите описание изображения здесь

...