<commit_before>var _ = require('lodash');
var fs = require('fs');
var cluster = require('cluster');
var logger = require('log4js').getLogger('SATAN');

var Satan = function(defaultConfig, configFilePath) {
	this.workers = {};
	this.workerCount = 0;
	this.loadingCount = 0;
	this.targetWorkerCount = 0;
	this.defaultConfig = defaultConfig;
	this.configFile = {};
	this.configFilePath = configFilePath;
};

Satan.prototype.refreshConfiguration = function() {
	if (this.configFilePath) {
		try {
			this.configFile = JSON.parse(fs.readFileSync(this.configFilePath));
		} catch (e) {
			logger.error('Failed to read config file! Continuing anyway with previous configuration...');
			logger.error(e);
		}
	}

	this.config = _.defaults({
		arguments: (this.defaultConfig.arguments || []).concat(this.configFile.arguments || [])
	}, this.defaultConfig, this.configFile, {
		instances: 1,
		schedulingPolicy: 'rr',
		nodeArguments: process.execArgs
	});

	this.targetWorkerCount = this.config.instances;
};

Satan.prototype.prepare = function() {
	var self = this;

	switch (this.config.schedulingPolicy) {
		case 'rr':
			cluster.schedulingPolicy = cluster.SCHED_RR;
			break;
		case 'none':
			cluster.schedulingPolicy = cluster.SCHED_NODE;
			break;
		default:
			throw new Error("Invalid scheduling policy " + this.config.schedulingPolicy);
			break;
	}

	cluster.setupMaster({
		execArgs: this.config.nodeArguments,
		exec: this.config.script,
		args: this.config.arguments
	});

	process.on('SIGHUP', function() {
		logger.debug('Caught SIGHUP!');
		self.reload();
	});
};

Satan.prototype.ensureWorkerCount = function() {
	var instanceDelta = function() {
		return this.targetWorkerCount - this.workerCount - this.loadingCount;
	}.bind(this);

	if (instanceDelta() > 0) {
		logger.info('Upscaling to %s worker(s).', this.targetWorkerCount);

		while (instanceDelta() > 0) {
			this.spawnWorker();
		}
	} else if (instanceDelta() < 0) {
		logger.info('Downscaling to %s worker(s).', this.targetWorkerCount);

		while (instanceDelta() < 0) {
			this.removeWorker(Object.keys[this.workers][0]);
		}
	} else {
		return;
	}
<commit_msg>Change from SIGHUP to SIGUSR2.<commit_after>var _ = require('lodash');
var fs = require('fs');
var cluster = require('cluster');
var logger = require('log4js').getLogger('SATAN');

var Satan = function(defaultConfig, configFilePath) {
	this.workers = {};
	this.workerCount = 0;
	this.loadingCount = 0;
	this.targetWorkerCount = 0;
	this.defaultConfig = defaultConfig;
	this.configFile = {};
	this.configFilePath = configFilePath;
};

Satan.prototype.refreshConfiguration = function() {
	if (this.configFilePath) {
		try {
			this.configFile = JSON.parse(fs.readFileSync(this.configFilePath));
		} catch (e) {
			logger.error('Failed to read config file! Continuing anyway with previous configuration...');
			logger.error(e);
		}
	}

	this.config = _.defaults({
		arguments: (this.defaultConfig.arguments || []).concat(this.configFile.arguments || [])
	}, this.defaultConfig, this.configFile, {
		instances: 1,
		schedulingPolicy: 'rr',
		nodeArguments: process.execArgs
	});

	this.targetWorkerCount = this.config.instances;
};

Satan.prototype.prepare = function() {
	var self = this;

	switch (this.config.schedulingPolicy) {
		case 'rr':
			cluster.schedulingPolicy = cluster.SCHED_RR;
			break;
		case 'none':
			cluster.schedulingPolicy = cluster.SCHED_NODE;
			break;
		default:
			throw new Error("Invalid scheduling policy " + this.config.schedulingPolicy);
			break;
	}

	cluster.setupMaster({
		execArgs: this.config.nodeArguments,
		exec: this.config.script,
		args: this.config.arguments
	});

	process.on('SIGUSR2', function() {
		logger.debug('Caught SIGUSR2!');
		self.reload();
	});
};

Satan.prototype.ensureWorkerCount = function() {
	var instanceDelta = function() {
		return this.targetWorkerCount - this.workerCount - this.loadingCount;
	}.bind(this);

	if (instanceDelta() > 0) {
		logger.info('Upscaling to %s worker(s).', this.targetWorkerCount);

		while (instanceDelta() > 0) {
			this.spawnWorker();
		}
	} else if (instanceDelta() < 0) {
		logger.info('Downscaling to %s worker(s).', this.targetWorkerCount);

		while (instanceDelta() < 0) {
			this.removeWorker(Object.keys[this.workers][0]);
		}
	} else {
		return;
	}

{'fraction_non_alphanumeric': 0.15160009343611305, 'fraction_numerical': 0.005372576500817566, 'mean_word_length': 4.420253164556962, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '1008729', 'n_tokens_mistral': 1526, 'n_tokens_neox': 1385, 'n_words': 276}