2012-11-16 38 views
0

我已经设置了节点服务器来保存日志信息。预计会有非常高的请求数量。我正在与mongo数据存储一起工作,但这种性能太不可靠了。阅读报道方面的数据往往需要很长的时间。所以我切换到一个经典的,MySQL。如果您准备批量插入而不是单点插入,显然有很大的写入吞吐量优势。所以,我发现这个家伙:node.js,可以通过外部请求修改运行函数中的变量

https://gist.github.com/3078520

我喜欢它的简单。它在几条线上,非常强大。它有两个主要功能add(),它将向队列添加一条记录,然后在队列达到一定大小后再调用flush()。然后它有flush()其加入队列成一个长字符串,并创建一个长BULK INSERT语句时,再运到MySQL驱动(我简化,从提供的链接功能:

this.flush = function() { 
/*1*/ var sql = queryTemplate.replace('{values}', '\n('+ queue.join('),\n(') +')'); 
/*2*/ handle.query(sql, callback); 
/*3*/ queue = []; 
} 

这实质上是一种类函数是请求处理程序拥有的单个类实例的一部分,所以我的问题是,这是安全的吗?queue是一个类变量,当调用flush()时,它处理队列。调用flush(),执行第1行以使sql语句(只是一个字符串),然后调用另一个add(),它将某些内容添加到queue,然后第一个进程调用query()函数,然后清空队列。在这种情况下,由第二个进程添加的记录将会丢失,因为第一个进程在创建sql语句时不会知道它,并在清除queue时将其清除。这可能吗?

这个问题的更概括的形式如下。一旦函数开始执行,其他任何东西都可以从外部影响其范围之外的变量?这里是一个非常简单的例子,就是它曾经可能做到在这个例子中,假设的console.log不同请求调用这两个函数:

var global_number; 
function a(){ 
    global_number=2; 
} 
function b(){ 
    global_number=1; 
    if(global_number==2){ 
    console.log("a() influenced global_number in the middle of b()'s execution") 
    } 
} 

这主要是/否的问题,但我正在寻找多一点。一个简单的解释或链接到一个页面,我可以学习更多将是伟大的!谢谢!

回答

1

是的,如果函数的执行是异步的,那么全局变量拥有的数据可能会有问题。这是测试场景;

var globalVariable = 10; 

function a() 
{ 
    var timer = setInterval(function() { 
     globalVariable--; 
     console.log(globalVariable) 
    }, 1000); 
} 

function b() 
{ 
    setTimeout(function() { 
     globalVariable = 20; 
    }, 3000); 
} 

a(); 
b(); 

这将出认沽:

9 
8 
7 
19 
18 
17 
16 

如果你问的功能执行中断它不是异步的,没办法!看例子。

var globalVariable = 1000000000; 
function a() { 
    for(var i=0; i < 1000000000; i++) 
    { 
     if(globalVariable == 20000) console.log('From a() : ' + globalVariable); 
     globalVariable--; 
     if(globalVariable == 0) break; 
    } 
} 

function b() { 
    setTimeout(function() { 
     console.log('From b() : ' + globalVariable); 
     globalVariable = 20000; 
     console.log('From b() : ' + globalVariable); 
    }, 1); 
} 

b(); 
a(); 

这将始终输出:

From a() : 20000 
From b() : 0 
From b() : 20000 

所以,你的问题,答案是否定的,你不能中断同步功能的执行。

但是;在你的代码片段的例子中,似乎可以清空queue,因为你已经在第1行使用了queuequeue.join中的数据。另一方面,这种方法受到回滚操作的影响。例如,当sql返回错误时,您可能无法重新填充queue

+0

关于错误问题的好处,我不关心它,但记住它很好。除此之外,按照我描述的方式,数据丢失的功能是否安全?上面的答案在这方面并不十分清楚。 – Landon

+0

第一句话是关于你的实际问题。不,这是不安全的,异步函数可以修改全局数据,而使用相同全局变量的所有其他进程都会受到操作数据的影响。 –

+0

更新了答案,查看输出结果,您将轻松获得该技巧。 –

1

如果一个函数是同步的,那么在函数开始执行和完成之间不会影响该函数引用的变量。然而,如果函数调用异步函数(例如MySQL查询),那么函数本身就是异步的,而其他代码可以在函数运行时间和时间之间修改函数的父/全局作用域中的变量异步函数的回调运行。

+0

我知道'query()'调用是异步的,将在稍后的时间点返回,但是当它被调用时它知道sql语句。但功能的其余部分是同步的吗?按照我所描述的方式,是否有可能在上面的函数中丢失记录? – Landon

相关问题