2017-12-22 12 views
0

私は、ページからエラーを収集してDBに格納し、グラフAPIを使用して情報を視覚的に表示するという小さな考えに取り組んでいます。ノード/ MySQLコード:〜800レコードを挿入しようとすると 'ER_PARSE_ERROR'

8つのサイトがあり、それぞれに100個のエントリがあります.1回あたり800トランザクションです。 私は各サイトをループし、エラーのテーブルをサブループして収集します。

すべての800個のエントリについて、それらのサブループのそれぞれに挿入クエリを作成すると、うまく動作しますが、非常に多くのトランザクションから数分後にメモリリークが発生します。

私は配列の配列にすべての800のエントリをキューイングしてから、各繰り返しの最後に複数の挿入を実行しようとしましたが、ER_PARSE_ERRORを取得しています。

var tabletojson = require('tabletojson'); 
var mysql = require("mysql"); 
var striptag = require("striptags"); 
var fs = require("fs"); 
var path = require('path'); 

var startCollector; 
var iterations = 0; 
var insertions = 0; 
var duplicated = 0; 

var datas = []; 

var clients = ["ClientA", "ClientB", "ClientC", "ClientD", "ClientE", "ClientF", "ClientG", "ClientH"]; 
var appDir = path.dirname(require.main.filename); 

var errorList = ["err1", "err2", "err3", "err4", "err5", "err6"]; 

var con = mysql.createPool({ 
    host: "localhost", 
    user: "User", 
    password: "Password", 
    database: "errors" 
    }); 

function CollectErrors() { 
    startCollector = new Date(); 
    for(var a = 0; a < clients.length; a++) { 
     (function(a) { 
      tabletojson.convertUrl("http://example.com" + clients[a] + "/page.php?limit=100", { stripHtmlFromCells: false }, function(response) { 
      var rs = response[0]; 
       for(var l = rs.length-1; l > -1; l--) { 
        var newDate = formatDate(striptag(rs[l]["Date"]), striptag(rs[l]["Time"])); 
        var user = getUser(striptag(rs[l]["User"])); 
        var msg = striptag(rs[l]["Error"]); 
        var splitError = rs[l]["Error"].split("<a href=\""); 
        var link = getUrl(splitError[1]); 
        var id = getId(link); 
        var type = getType(striptag(splitError[0])); 
        var temp = [newDate, link, type, user, clients[a], id, msg]; 
        datas.push(temp); 
       } 
       }); 
     })(a); 
    } 
    con.getConnection(function(err, connection) { 
     connection.query("INSERT IGNORE INTO entries (time, url, type, author, client, uid, message) VALUES ?", [datas], function(err, rows) { 
      console.log(err); 
     }); 
     connection.release(); 
     datas = []; 
    }); 
    setTimeout(CollectErrors, 10000); 

} 



function formatDate(date, time) { 
    var newdate = date.split("/").reverse().join("-"); 
    var newtime = time+":00"; 
    return newdate + " " + newtime; 
} 

function getUrl(uri) { 
    return "http://example.com/"+uri.split("\">Details")[0]; 
} 

function getId(url) { 
    return decodeURIComponent((new RegExp('[?|&]' + "id" + '=' + '([^&;]+?)(&|#|;|$)').exec(url) || [null, ''])[1].replace(/\+/g, '%20')) || null; 
} 

function getType(error) { 
    for(var a = 0; a < errorList.length; a++) { 
     if(error.indexOf(errorList[a]) !== -1) { 
      return errorList[a]; 
     } 
    } 
    return "Other"; 
} 

function getUser(user) { 
    if(user == "" || user == "&#xA0;" || user == null) { 
     return "System"; 
    } 
    return user; 
} 


CollectErrors(); 

私もmysql.createConnectionを試してみましたが、これも同じ問題をもたらしました。

私は過去12時間立ち往生して何が間違っているのかわかりません.Datasテーブルに文字列だけを入力しようとしましたが、同じエラーが発生しました。

答えて

2

コードを変更してES6を使用し、正しいモジュール機能を使用しました。
便利なリンク:correct pooling with mysql、正しいinsert queryasync/awaitIIFEenhanced object

const tabletojson = require('tabletojson'), 
 
    mysql = require("mysql"), 
 
    striptag = require("striptags"), 
 
    fs = require("fs"), 
 
    path = require('path'); 
 

 
const startCollector, 
 
    iterations = 0, 
 
    insertions = 0, 
 
    duplicated = 0; 
 

 
let datas = []; 
 

 
const clients = ["ClientA", "ClientB", "ClientC", "ClientD", "ClientE", "ClientF", "ClientG", "ClientH"]; 
 
const appDir = path.dirname(require.main.filename); 
 

 
const errorList = ["err1", "err2", "err3", "err4", "err5", "err6"]; 
 

 
const con = mysql.createPool({ 
 
    host: "localhost", 
 
    user: "User", 
 
    password: "Password", 
 
    database: "errors" 
 
}); 
 
// We'll use async/await from ES6 
 
const collectErrors = async() => { 
 
    // Up to here I've only changed syntax to ES6 
 
    let startCollector = new Date(); 
 

 
    // We'll try to iterate through each client. And we use here for..of syntax to allow us using await 
 
    for (let client of clients) { 
 
    // Please, check that client value return correct data. If not, change for..of to your for..each and client variable to clients[a] 
 
    const tbj = await tabletojson.convertUrl("http://example.com" + client + "/page.php?limit=100", { 
 
     stripHtmlFromCells: false 
 
    }); 
 
    const result = tgj[0]; 
 
    for (rs of result) { 
 
     // I can't check this part, but I hope your example was with correct values. 
 
     let newDate = formatDate(striptag(rs[l]["Date"]), striptag(rs[l]["Time"])); 
 
     let user = getUser(striptag(rs[l]["User"])); 
 
     let link = getUrl(splitError[1]); 
 
     let msg = striptag(rs[l]["Error"]); 
 
     let id = getId(link); 
 
     let splitError = rs[l]["Error"].split("<a href=\""); 
 
     let getType = getType(striptag(splitError[0])); 
 
     // ES6 enhanced object syntax 
 
     datas.push({ 
 
     newDate, 
 
     user, 
 
     msg, 
 
     id, 
 
     splitError, 
 
     link, 
 
     getType, 
 
     temp: [newDate, link, type, user, client, id, msg] 
 
     }); 
 
    } 
 
    } 
 
    // OK, here we have fulfilled datas array. And we want to save it. 
 
    con.getConnection((err, connection) => { 
 
    // Please, notice, here I've changed your insert query to prepared statement. 
 
    connection.query("INSERT IGNORE INTO entries SET ?", datas, (err, rows) => { 
 
     console.log(err); 
 
     connection.release(); 
 
     datas = []; 
 
    }); 
 
    }); 
 
    // I don't see why do you need timeout here, so I've left it commented. 
 
    // setTimeout(CollectErrors, 10000); 
 
}; 
 

 
// Here your other methods go.... 
 

 
// And to call your async function we'll use IIFE 
 
(async() => { 
 
    await collectErrors(); 
 
})();

は、おそらくmysqlの挿入でエラーがあるかもしれませんが、それは確かではありません。発生した場合は、コメントを記入してください。私はそれをお手伝いします。

+0

setTimeoutは必須です。設定間隔ごとに無制限に実行するにはこのスクリプトが必要です。 – arleitiss

+0

@arleitissこのモジュールでhttps://www.npmjs.com/package/node-cronを見ると、あなたのスクリプトは堪能な方法で処理できます – Grynets

+0

この回答を受け入れています。 私は、提供された完全なソリューションを使用していませんでしたが、いくつかの部分を混在させました。 これは現在必要に応じて動作します。 – arleitiss

関連する問題