<commit_before>async = require "async"
_ = require "underscore"
{db, ObjectId} = require "./mongojs"
BSON=db.bson.BSON
logger = require "logger-sharelatex"
logger.initialize("track-changes-packworker")
LockManager = require "./LockManager"
PackManager = require "./PackManager"

# this worker script is forked by the main process to look for
# document histories which can be packed

LIMIT = Number(process.argv[2]) || 1000
DOCUMENT_PACK_DELAY = Number(process.argv[3]) || 1000
TIMEOUT = Number(process.argv[4]) || 30*60*1000

shutDownRequested = false
setTimeout () ->
	logger.log "pack timed out, requesting shutdown"
	# start the shutdown on the next pack
	shutDownRequested = true
	# do a hard shutdown after a further 5 minutes
	setTimeout () ->
		logger.error "HARD TIMEOUT in pack worker"
		process.exit()
	, 5*60*1000
, TIMEOUT

logger.log "checking for updates, limit=#{LIMIT}, delay=#{DOCUMENT_PACK_DELAY}, timeout=#{TIMEOUT}"

finish = () ->
	logger.log 'closing db'
	db.close () ->
		logger.log 'exiting from pack worker'
		process.exit()

processUpdates = (pending) ->
	async.eachSeries pending,	(doc_id, callback) ->
		PackManager.packDocHistory doc_id, (err, result) ->
			if err?
				logger.error {err, result}, "error in pack worker"
				return callback(err)
			if shutDownRequested
				logger.error "shutting down pack worker"
				return callback(new Error("shutdown"))
			setTimeout () ->
				callback(err, result)
			, DOCUMENT_PACK_DELAY
	, (err, results) ->
		if err?
			logger.error {err}, 'error in pack worker processUpdates'
		finish()

# find the documents which can be packed, by checking the number of
# unpacked updates in the docHistoryStats collection

db.docHistoryStats.find({
	update_count: {$gt : PackManager.MIN_COUNT}
}).sort({
	update_count:-1
}).limit LIMIT, (err, results) ->
	if err?
		logger.log {err}, 'error checking for updates'
		finish()
		return
	results = _.filter results, (doc) ->
		if doc.last_checked? and doc.last_checked > doc.last_update
			# skip documents which don't have any updates since last check
			return false
		else if doc.last_packed? and doc.last_packed > doc.last_update
			# skip documents which don't have any updates since last pack
			return false
		else
			return true
	pending = _.pluck results, 'doc_id'
	logger.log "found #{pending.length} documents to pack"
	processUpdates pending
<commit_msg>suppress error in normal shutdown case<commit_after>async = require "async"
_ = require "underscore"
{db, ObjectId} = require "./mongojs"
BSON=db.bson.BSON
logger = require "logger-sharelatex"
logger.initialize("track-changes-packworker")
LockManager = require "./LockManager"
PackManager = require "./PackManager"

# this worker script is forked by the main process to look for
# document histories which can be packed

LIMIT = Number(process.argv[2]) || 1000
DOCUMENT_PACK_DELAY = Number(process.argv[3]) || 1000
TIMEOUT = Number(process.argv[4]) || 30*60*1000

shutDownRequested = false
setTimeout () ->
	logger.log "pack timed out, requesting shutdown"
	# start the shutdown on the next pack
	shutDownRequested = true
	# do a hard shutdown after a further 5 minutes
	setTimeout () ->
		logger.error "HARD TIMEOUT in pack worker"
		process.exit()
	, 5*60*1000
, TIMEOUT

logger.log "checking for updates, limit=#{LIMIT}, delay=#{DOCUMENT_PACK_DELAY}, timeout=#{TIMEOUT}"

finish = () ->
	logger.log 'closing db'
	db.close () ->
		logger.log 'exiting from pack worker'
		process.exit()

processUpdates = (pending) ->
	async.eachSeries pending,	(doc_id, callback) ->
		PackManager.packDocHistory doc_id, (err, result) ->
			if err?
				logger.error {err, result}, "error in pack worker"
				return callback(err)
			if shutDownRequested
				logger.error "shutting down pack worker"
				return callback(new Error("shutdown"))
			setTimeout () ->
				callback(err, result)
			, DOCUMENT_PACK_DELAY
	, (err, results) ->
		if err? and err.message != "shutdown"
			logger.error {err}, 'error in pack worker processUpdates'
		finish()

# find the documents which can be packed, by checking the number of
# unpacked updates in the docHistoryStats collection

db.docHistoryStats.find({
	update_count: {$gt : PackManager.MIN_COUNT}
}).sort({
	update_count:-1
}).limit LIMIT, (err, results) ->
	if err?
		logger.log {err}, 'error checking for updates'
		finish()
		return
	results = _.filter results, (doc) ->
		if doc.last_checked? and doc.last_checked > doc.last_update
			# skip documents which don't have any updates since last check
			return false
		else if doc.last_packed? and doc.last_packed > doc.last_update
			# skip documents which don't have any updates since last pack
			return false
		else
			return true
	pending = _.pluck results, 'doc_id'
	logger.log "found #{pending.length} documents to pack"
	processUpdates pending

{'fraction_non_alphanumeric': 0.1109723089735582, 'fraction_numerical': 0.011659379554445138, 'mean_word_length': 4.296582138919515, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, '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': '366774', 'n_tokens_mistral': 1637, 'n_tokens_neox': 1475, 'n_words': 490}