overleaf/services/spelling/app/coffee/ASpellWorkerPool.coffee

63 lines
1.6 KiB
CoffeeScript
Raw Normal View History

2015-03-04 11:43:59 -05:00
ASpellWorker = require "./ASpellWorker"
_ = require "underscore"
2015-03-10 09:33:05 -04:00
logger = require 'logger-sharelatex'
2015-03-04 11:43:59 -05:00
class ASpellWorkerPool
2015-03-10 09:33:05 -04:00
MAX_REQUESTS: 100*1024
MAX_WORKERS: 32
2015-03-04 11:43:59 -05:00
constructor: (@options) ->
@PROCESS_POOL = []
@timeout = 1000
create: (language) ->
2015-03-10 09:33:05 -04:00
if @PROCESS_POOL.length >= @MAX_WORKERS
logger.log maxworkers: @MAX_WORKERS, "maximum number of workers already running"
return null
2015-03-04 11:43:59 -05:00
worker = new ASpellWorker(language, @options)
worker.pipe.on 'exit', () =>
@cleanup
@PROCESS_POOL.push(worker)
return worker
cleanup: () ->
active = @PROCESS_POOL.filter (worker) ->
worker.state != 'killed'
@PROCESS_POOL = active
check: (language, words, timeout, callback) ->
# look for an existing process in the pool
availableWorker = _.find @PROCESS_POOL, (cached) ->
cached.language == language && cached.isReady()
if not availableWorker?
worker = @create(language)
else
worker = availableWorker
2015-03-10 09:33:05 -04:00
if not worker?
# return error if too many workers
callback(new Error("no worker available"))
return
if worker.idleTimer?
clearTimeout worker.idleTimer
worker.idleTimer = null
killTimer = setTimeout () ->
2015-03-04 11:43:59 -05:00
worker.pipe.kill('SIGKILL')
, timeout || 1000
2015-03-10 09:33:05 -04:00
worker.check words, (err, output) =>
clearTimeout killTimer
2015-03-04 11:43:59 -05:00
callback(err, output)
2015-03-10 09:33:05 -04:00
# queue a shutdown if worker is not used
if worker.count > @MAX_REQUESTS
worker.shutdown("reached limit of " + @MAX_REQUESTS + " requests")
else
worker.idleTimer = setTimeout () ->
worker.shutdown("idle worker")
worker.idleTimer = null
, 1000
2015-03-04 11:43:59 -05:00
module.exports = ASpellWorkerPool