Nodejs - 如何终止正在运行的SQLite查询

时间:2014-12-19 17:58:02

标签: ajax node.js sqlite sockets socket.io

可能类似的问题:

SQL: Interrupting a query

Is there a way to abort an SQLite call?

大家好, 我实际上使用socket.io和sqlite3模块在SQLite数据库上执行SELECT查询。当用户单击OpenLayers Map时,它会向服务器发送信号(通过socket.io),通过执​​行空间请求(如交集,联合......使用Spatialite扩展)收集信息,然后最终将数据发送回客户端(这些是长时间运行的查询(取决于几何的数量))以在用户点击的地图上显示弹出窗口。

问题是:如果用户在地图上多次点击,向服务器发送许多请求,则只有最后一个请求很重要。想象一下,如果一个查询需要5秒才能执行,并且用户在地图上一秒钟内点击3次(他只想要他点击使用的最后一个位置),那么服务器将执行3次查询,然后发回3个信号通过socket.io(并打开3个弹出窗口,我们只需要打开最后一个)!是否有任何解决方案可以使用nodejs杀死/中止正在运行的sqlite查询?

示例代码:

socket.on('askForInfo', function (data) {
    sendInfo(socket, data.latitude, data.longitude);
});

sendInfo定义:

function sendInfo(socket, lat, lng) {
    // Database connection
    var db = new sqlite.Database('some file.sqlite', sqlite.OPEN_READONLY);

    // Load Spatialite extension
    db.loadExtension('mod_spatialite', function(err) {
        // Query doing spatial request
        db.get("VERY LONG SQL QUERY", function(err, row) {
            // Send the data gathered from database
            socket.emit('sendData', row['some sql column']);
        });
    });
}

我想做类似的事情:

if ("sendInfo didn't finished to emit any signal through socket"
    AND "user did another resquest") 
then
    "kill all running sendInfo function execution and sql query"

我知道如果有很多用户连接起来,那就不会那样工作(我可能需要使用会话来了解该功能实际上正在收集数据的用户)。但即使只有一个用户,我也找不到任何解决方案。

我尝试使用AJAX(jquery)而不是socket.io。我可以中止xhr请求,但SQL查询仍在运行,即使请求中止,直到她完成(使用大量无用的资源)

提前感谢您的回答。

1 个答案:

答案 0 :(得分:2)

感谢你的回答Qualcuno。

我找到了一个解决方案,使用child_process从另一个进程查询数据库,如果用户再次请求则终止该数据库。

var cp = require('child_process');
// more stuff ...

socket.on('askForInfo', function (data) {
    // if process is connected, kill it (query isn't terminated)
    if (child.connected) {
        child.kill();
    }

    // create a new process executing 'query_database.js'
    child = cp.fork('./query_database.js', [
        data.latitude, data.longitude
    ]);

    // when invoking [ process.send(some_data_here) ] in child process, fire this event to send data to the user
    child.on('message', function(d) {
        socket.emit('sendData', d)
    };
});