<commit_before>var fs = require('fs');
var spawn = require('child_process').spawn;
var WebSocketServer = require('websocket').server;

var filename = process.argv[2];
if (!filename)
	return console.log("Usage: node server.js <LOG> [<SSL_CERT> <SSL_KEY>]");

if (process.argv.length >= 5) {
	https = require('https');
	var server = https.createServer({
		cert: fs.readFileSync(process.argv[3]),
		key: fs.readFileSync(process.argv[4])
	}, function(req,res){
		res.writeHead(400);
		res.end();
	});
} else {
	http = require('http');
	var server = http.createServer(function(req,res){
		res.writeHead(400);
		res.end();
	});
}
server.listen(31216);

var ws = new WebSocketServer({
	httpServer: server,
	autoAcceptConnections: false
});

ws.on('request', function(req){
	var con = req.accept('cloogle-stats', req.origin);
	var tail = spawn("tail", ["-n", "1", "-f", filename]);

	con.on('close', function(reason, desc){
		tail.kill();
	});
	
	tail.stdout.on('data', function(data){
		data = JSON.parse(data);
		con.sendUTF(JSON.stringify(data['request']));
	});
});<commit_msg>Don't let stats server break when two log entries interleave<commit_after>var fs = require('fs');
var spawn = require('child_process').spawn;
var WebSocketServer = require('websocket').server;

var filename = process.argv[2];
if (!filename)
	return console.log("Usage: node server.js <LOG> [<SSL_CERT> <SSL_KEY>]");

if (process.argv.length >= 5) {
	https = require('https');
	var server = https.createServer({
		cert: fs.readFileSync(process.argv[3]),
		key: fs.readFileSync(process.argv[4])
	}, function(req,res){
		res.writeHead(400);
		res.end();
	});
} else {
	http = require('http');
	var server = http.createServer(function(req,res){
		res.writeHead(400);
		res.end();
	});
}
server.listen(31216);

var ws = new WebSocketServer({
	httpServer: server,
	autoAcceptConnections: false
});

ws.on('request', function(req){
	var con = req.accept('cloogle-stats', req.origin);
	var tail = spawn("tail", ["-n", "1", "-f", filename]);

	con.on('close', function(reason, desc){
		tail.kill();
	});
	
	tail.stdout.on('data', function(data){
		try {
			data = JSON.parse(data);
			con.sendUTF(JSON.stringify(data['request']));
		} catch (e) {
			console.error(e);
		}
	});
});
{'fraction_non_alphanumeric': 0.2018716577540107, 'fraction_numerical': 0.0142602495543672, 'mean_word_length': 5.0675675675675675, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5238260', 'n_tokens_mistral': 847, 'n_tokens_neox': 788, 'n_words': 163}